您的位置:首页 > 其它

利用已有异构服务 轻松构建SOA应用

2008-09-26 15:26 561 查看
  应全球化网络、各种异构信息系统,以及企业对敏捷性的需求,系统常规的架构已经形成。重新构建所有新应用、为遗留系统编写特定接口程序,或者重写当前
的应用程序,这些曾经的任务都已一去不返。由于Web服务的推动,面向服务的架构(SOA)现在成为设计信息系统时通常会优先考虑的方案。
  
  SOA的概念是把当前的信息系统功能看作是可以以松耦合方式访问、与技术平台无关的“服务”,而把应用程序看作对服务请求的编排方式。这就是为什么SOA通常都有工作流或流程编排概念的原因。
  
  企业服务总线(ESB)是SOA的实现途径之一。它是连接各种不同服务并对其进行编排的中间件。根据这些概念,JBI规范(Java Specification Request 208)定义了一个标准的集成框架。
  
  本文将通过一个开源JBI容器Petals ESB来解释怎样连接已有的异构服务,并实现一个在线旅行社的实际Web应用。
  
JBI简介
  
 
 JBI(Java Business
Integration,Java业务集成)规范定义了安装集成组件的标准方法。其目的是创建一个可以在企业信息系统中实现SOA的集成方案。这些组件以
插件的形式安装到JBI环境中,并通过JBI环境以松耦合的方式提供或使用服务。而JBI环境则负责这些组件之间的通信。
  
  有两种组件可以插入JBI环境:
  
* 服务引擎(Service engine):提供服务逻辑,比如可扩展样式表转换语言(XSLT)或业务流程执行语言编排(BPEL)。
* 绑定组件(Binding component):是连接外部服务或应用程序的“连接器”。它们可以与各种协议进行通信,比如SOAP、Java消息服务(JMS)、远程方法调用(RMI)或者ebXML。
  
 
 这些可配置的组件使异构服务之间的通信成为可能。JBI规范引入服务装配器(service
assembly)概念,定义了这些组件的配置方案与互相之间的关系。这些组件(引擎或绑定)的作用就是暴露外部与内部的服务。所有JBI环境中暴露的服
务都可以通过服务终端和服务地址进行访问。
  
  组件之间交换信息称为信息交换。交换模式是一种发送/接收的模式。
用JBI实现在线旅行社
  
  本文实现的在线旅行社可以提供用户预订机票和
旅店,并向用户发送邮件确认用户的预约。为实现这一功能,网站将向工作流引擎发送用户以XML格式提供的所有信息,然后该工作流引擎会联系航空公司订购机
票,并向旅店连锁机构预订房间,最后它会通过邮件引擎向用户发送一封确认信。
  
  尽管此过程中所使用的数据交换格式是XML,但各种服务请求或提供的XML模式不尽相同。因此,可扩展样式表转换语言(XSLT)引擎就被用来进行从XML向其它格式的转换。
  
  后文会详细讨论这个业务过程,这里先看图1。图1描述怎样使用Petals ESB构建整个应用。
  
  


  
  图1 应用架构
  
  现在我们来讨论该架构的各个关键组成部分。
  
  服务装配器
  
 
 服务装配器(service
assembly)描述如何配置一个JBI组件使其能集成到应用中。它以一个简单的zip压缩包方式部署在JBI容器中。容器分析压缩包中的所有内容,并
根据这些内容配置相关的组件。组件的配置即是一个服务单位(service
unit)。当我们使用服务单位来配置一个组件时,我们称之为部署一个配置(artifact)。请注意,服务单位的内容对容器来说是不透明的,它只提供
给组件。
  
  如果服务装配器包含对服务之间关系的定义(即连接,connections),容器就会创建这些连接。可以视连接为真正的服务终端别名。
  
  如图2,服务装配器是一个zip压缩包,它包含XML描述符文件,定义向哪个组件提供服务单位以及服务之间的连接。服务装配器还包含要向各个组件部署的服务单位。这些服务单位也是zip压缩包。
  
  


  
  图2 服务装配器
  
  简单地说,服务装配器的作用就是定义一系列服务之间的关系,从而以SOA的方式创建应用。如果容器中有多个服务装配器,那么这些服务装配器应该可以在同样的服务上运行,并共享这些服务。
  
  服务单位
  
  服务单位是一系列部署到JBI组件中的元素。它包含一个组件能够读取的XML描述符,以及任何组件可以获取的配置。比如,一个XSLT引擎的服务单位包含一个XSL样式表,描述符文件告诉组件如果接收到某个特定服务终端发来的消息就必须使用该样式表。
  


  
  图3 服务单位
  
  ESB将服务单位包放在一个目录里,然后告诉组件的服务单位管理器(JBI组件的一部分)有新的服务单位可以调用,并指出存放服务单位的目录位置。组件的服务单位管理器把新服务注册到JBI环境中,然后配置组件以使用已注册的服务终端。
  


  
  图4 在组件上配置服务单位
  
  当组件收到调用某个服务终端消息的时候,它就会知道该用哪一个配置。
  
  


  
  图5 为特定服务终端使用配置
  
  连接器
  
 
 连接器是在服务配置器的描述符里定义的,可以视其为真正的服务终端的别名。比如,一个组件可以描述“我要向一个称作My
Endpoint的服务终端发送一条消息”,连接器就可以认为My Endpoint实际上就是My Real Endpoint。这样,当组件向My
Endpoint发送消息时,消息就会被发送到My Real Endpoint。
  
  使用这样一种机制的意义在于,可以动态地
对组件之间的连接进行重新配置。比如,配置一个组件——旅行社的工作流程引擎——来调用叫做“航空服务终端”的服务。后来,由于旅行社与航空公司合作关系
的变化,连接器要把航空服务终端连接到“低消费的航空公司终端”或“另一个航空公司终端”。服务使用者不需要做出任何变更,通过部署包含不同连接器的各种
服务配置器,应用就会动态地更改所使用的服务。
  
  


  
  图6 更换一个连接器

  旅行社应用
  
  旅行社应用的全部过程按以下顺序进行:
  
  1. 网站使用SOAP请求把用户的预订要求发送到SOAP绑定组件。这个消息就是网站的XML内容。注意,这个交流过程是在JBI外部发生的。

  2. 现在开始进入JBI环境。SOAP绑定组件的配置会通过一个消息转换器把这个网站的XML内容发送到“预订工作流程终端”(在BPEL引擎上)。
  3. BPEL引擎把网站的XML内容发送到XSLT_1_Endpoint(在XSLT引擎上)。
  4. XSLT引擎把网站的XML内容转换为航空服务可以读取的格式,并以航空服务请求XML格式返回。

  5. BPEL引擎把网站的XML内容发送到XSLT_2_Endpoint(在XSLT引擎上)。
  6. XSLT引擎把网站的XML内容转换为旅店服务可以读取的格式,并以旅店服务请求XML格式返回。
  7. BPEL引擎把航空服务请求XML发送到“航空服务终端”,解析为“我的航空公司终端”(在SOAP绑定组件上)。
  8. SOAP绑定组件的配置会通过发送一个SOAP请求把航空服务请求XML发送到“我的航空公司”Web服务(在JBI外部);然后得到经过确认的航空服务响应XML,并被返回BPEL引擎。
  9. BPEL引擎把旅店服务请求XML发送到“旅店终端”,解析为“我的旅店终端”(在RMI绑定组件上)。
  10. RMI绑定组件的配置会以RMI调用的形式把旅店服务请求XML发送到“我的旅店”RMI服务器(在JBI外部);然后得到经过确认的旅店服务响应XML,并被返回BPEL引擎。
  11. 根据这两项预订,BPEL引擎把航空服务响应XML和旅店服务响应XML合并为航空/旅店服务响应XML;然后把这个XML发送到XSLT_3_Endpoint(在XSLT引擎上)。
  12. XSLT引擎把航空/旅店服务响应XML转换为概述这些预订的文本;然后以邮件XML的格式返回到旅行社工作流引擎。

  13. BPEL引擎把邮件XML发送到邮件终端(在邮件绑定引擎上)。
  14. 邮件绑定引擎把邮件XML发送给用户(在JBI外部)。过程结束。
  
  组件
  
 
 应用所需的JBI组件有SOAP绑定组件(与网站和航空公司的Web服务进行通信)、JMS绑定组件(与旅店JMS服务进行通信)、XSLT引擎
(XML转换)、邮件引擎(向客户发送确认邮件)和BPEL引擎。这些JBI组件都是用Petals JBI容器进行配置的。
  
  要创建应用,只要把这些组件安装到JBI容器。到此,架构应该是如图7所示的样子:
  
  


  
  图7 组件安装后
  
  这里注意,邮件引擎在本地向JBI环境开放它唯一的服务终端,因为它不需要任何配置,并且总是执行同样的任务(实际上就是发送邮件)。
  
  组件安装后,我们必须对它们进行配置。因此,我们要创建能把这些元素连接到一起的服务装配器。服务装配器由以下所述服务单位构成。
  
  网站服务单位
  
  创建一个服务单位部署到SOAP绑定组件上(SOAP BC)。这个服务单位定义了http://travel.com/workflowService的Web服务,并将指向内部的WorkflowEndpoint服务终端。
  
  SOAP BC通过这个服务单位使用WorkflowEndpoint服务终端:
  
  <jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi' ...>
   <services binding-component="true">
   <consumes service-name =" BookingWorkflowService "
   endpoint-name =" BookingWorkflowEndpoint " />
   <petals:address> http://travel.com/workflowService </petals:address>
   </services>
  </jbi>
  
  部署服务单位后,SOAP BC开放一个新的Web服务,即http://travel.com/workflowService。当外部有调用该Web服务的命令时(比如从网站),SOAP BC就把它传送到BookingWorkflowEndpoint服务终端,也就是应用的工作流引擎。
  
  预订流程服务单位
  
  这是用来部署到BPEL引擎上的服务单位。这个服务单位包含一个预订流程的BPEL定义,定义列出工作流程引擎必须调用的各种服务终端。这个流程定义是指向内部的BookingWorkflowEndpoint服务终端:
  
  <jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi' ...>
   <services binding-component="false">
   <provides service-name =" BookingWorkflowService "
   endpoint-name =" BookingWorkflowEndpoint " />
   <petals:address> file://travel-booking.bpel </petals:address>
   </services>
  </jbi>
  
  预订流程的BPEL文件描述了这个过程并储存在服务单位中。
  
  航空公司Web服务单位
  
  另一个要部署到SOAP BC上的服务单位是航空公司的Web服务单位。这个服务单位定义了将指向外部Web服务http://myairline.com/flightBookingService的MyAirlineCompanyEndpoint。
  
  SOAP BC通过这个服务单位提供MyAirlineCompanyEndpoint:
  
  <jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi' …>
   <services binding-component="true">
   <provides service-name =" MyAirLineCompanyService "
   endpoint-name =" MyAirLineCompanyEndpoint " />
   <petals:address> http://myairline.com/flightBookingService </petals:address>
   </services>
  </jbi>
  
  服务单位部署后,SOAP BC将在JBI环境中激活MyAirlineCompanyEndpoint服务终端。如果有JBI组件向这个服务终端发送消息,SOAP BC就将其传送到外部的http://myairline.com/flightBookingService Web服务,也就是航空服务预订的Web服务。
  
  旅店JMS服务单位
  
  旅店JMS服务单位跟航空服务单位相似。JMS BC提供负责向旅店JMS服务器转发消息的MyHotelEndpoint服务终端。
  
  XSLT服务单位
  
  XSLT引擎用于三种转换:
  
* 把网站的初始XML转换为航空服务请求XML
* 把网站的初始XML转换为旅店服务请求XML
* 把航空/旅店服务响应XML转换为邮件XML
  
  因此,必须有这三个服务单位,并且包含一个正确描述转换的XSL样式表。XSLT引擎将通过三个服务终端提供三种服务。
  
  航空公司与旅店的连接器
  
  如前面所述,我们可以使用各个连接器独立地把应用的工作流引擎连接到航空公司和旅店服务,并且通过部署新的服务装配器动态地配置这些连接。
  
  比如,一个指向MyLowCostAirLineCompany的连接器:
  
  <jbi version="1.0" xmlns…>
   <service-assembly>
   ...
   <connections>
   <connection>
   <consumer service-name ="AirLineService"
   endpoint-name ="AirLineServiceEndpoint"/>
   <provider service-name ="MyLowCostAirLineCompany"
   endpoint-name ="MyLowCostAirLineCompanyEndpoint"/>
   </connection>
   </connections>
   </service-assembly>
  </jbi>
  
  根据这段代码,如果有服务使用者(应用的工作流引擎)要使用AirlineService,其真正使用的服务将是MyLowCostAirLine。
  全局服务装配器
  
  所有这些服务单位都被封装在一个服务装配器中。服务装配器的描述符文件包含了这些连接器。
  
  


  
  图8 应用服务装配器
  
  服务装配器部署在Petals JBI容器中,所有的服务单位都传送给相应的组件。



  
  图9 部署应用服务装配器
  
  组件注册相应的服务终端,容器配置好连接器,然后应用就可以投入使用。
  
  


  
  图10 配置好的容器
  
总结
  
  JBI规范有效地利用SOA的理念,产生出一套利用当前服务来组合应用的标准方法。从根本上讲,JBI把ESB的概念标准化。
  
  利用Petals JBI容器构建SOA应用非常简单:使用一些标准的JBI绑定或引擎组件,写几个XML描述文件解释怎样连接到服务,然后把它们部署到Petals JBI容器里就可以了。
  
  有了这样一个容器,就无需再解决装配的难题,只需寻找合适的粒度编写或者使用相关的服务即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: