技术开发 频道

实现ESB与异构应用的无缝集成

    如果一个企业拥有许多由不同团队开发的异构应用,而这些应用之间需要互相交互,那么它们就会受到以下条件限制:

* 各个应用可能是使用不同的技术构建的,因此互相之间无法通过本地调用机制进行通信(比如J2EE应用和.Net应用)。
* 默认情况下各应用不会以可被目标应用读取的格式发送请求。而且,企业会有许多应用使用同一目标应用。
* 服务组件应该使用其固有的调用或请求机制。比如,一个既有的J2EE应用可以只接受Java消息服务(JMS)传来的请求。
* 企业正在经历一种架构的转变。在这种新的架构中,任何应用都将只接收它所能识别的消息,并且发送只能被它调用的服务识别的参数。

    另外企业可能还需要一个可以在不改变应用设计的前提下实现各应用的无缝集成的基础架构。企业服务总线(ESB)便是一种实现这种企业集成架构的方式。

    虽然各个企业都倾向于根据自身情况创建合适的ESB,但在设计的时候仍然要注意实现ESB的灵活性。ESB的创建没有固定的套路,它是一个优化服务提供者与服务消费之间的交互的中间层,可以应用在事件驱动、消息驱动或者服务驱动的环境中。

    本文将讨论如何构建一个基于Java、能够满足各种常见需求的可扩展ESB。

对ESB的要求

    ESB中的常见需求也就是ESB的共同特征:

1. 路由选择:ESB应该能提供一个有效、灵活的路由选择机制。
2. 转换:服务组件无需了解所调用的目标服务的请求规则。ESB应该能够根据服务请求者与目标的关系转换合理的请求格式,使目标服务能够识别。
3. 多协议传输:一个只能使用JMS或Web服务的ESB是没有多大价值的。ESB应该能够根据企业需求进行扩展,进而支持多种消息协议。
4. 安全:如果需要,ESB应该可以对服务访问进行认证与授权。

    图1显示了ESB的主要结构。它由三大部分组成:

1. 接收器:客户端可以通过各种各样的接口向ESB发送信息,比如,使用servlet接收从HTTP发向ESB的请求。同时,你可以用MDB(Message-driven bean)监听客户端发出的JMS消息。
2. 核心:这是ESB的主要组成部分。它负责实现ESB的路由、转换和安全功能。它包含一个接收传入的请求的MDB,并能根据接收到的消息内容进行合理的转换、路由选择和安全操作。关于路由选择、传输、转换和安全的详细信息可以用XML文档进行定义(这一部分将于稍后讨论)。
3. 分配器:所有处理发送信息的程序都在这一部分。你可以在这里随意加入任何消息传输处理程序(邮件、传真、ftp服务器等)。

图1 ESB的组成结构

    所有这些ESB组件通过一个列出了ESB所能进行的路由操作的XML文档构成一个整体。各种传输操作程序、转换程序和重试策略以及它们与各路由的连接都是通过这个XML文档完成的。

ESBConfiguration.xml

    下面的ESBConfiguration.xml可以让我们了解一些ESB的工作机制。其主要元素(element)有:

1. Beans:它包含零个或多个Bean元素。
2. Bean:它定义了创建和设置Bean类的基本方式。它有以下属性(attribute):

* name:代表这个bean的唯一的名称。
* className:bean类的全限定名(Fully qualified name)。

    每个bean可以有零个或多个Property子元素。每个Property元素都有一个唯一的属 性名以及一个存放Property值的Value类型的子元素。这些Property实际上是可以对bean类进行设置的JavaBeans类型成员。
3. RetryPolicies:它包含零个或多个RetryPolicy子元素。
4. RetryPolicy:这个元素为给定路由定义了重试(retry)规则。它有一个唯一的属性名。还有两个子元素,分别为MaxRetries和RetryInterval。
    Route:是EsbConfiguration的根元素,可以包含零个或多个相同类型的子元素。它代表了ESB的一个路由。它有以下属性:
* name:代表这个route的唯一的名称。
* retryPolicyRef:Retry规则的引用。它应该与RetryPolicy元素属性名相匹配。
* transformerRef:对表示转换的bean的引用。它应该与Bean元素属性名相匹配。
    Route元素可以包含零个或多个TransportHandlerRef类型的子元素,这种子元素应该指向代表这个route所使用的转换程序的bean、以及这个bean中用来发送消息的public方法名。此外,Route元素还可以包含一个DeadLetterDestination子元素,指向一个代表无效目标的路由。

    下面是一个可供参考的XML文档:
                       
<?xml version="1.0" encoding="UTF-8"?>
<EsbConfiguration xmlns="http://www.bss.org/esb/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Route name="creditService" retryPolicyRef="100-sec-retry" transformerRef="creditServiceTransform">
      <TransportHandler beanName="creditJMSTransport"/>
      <DeadLetterDestination routeName="DeadLetter"/>
      <AuthConstraint principals="app-1"/>
   </Route>
   <Route name="taxCalculationService" retryPolicyRef="500-sec-retry" transformerRef="taxCalcServiceTransform">
      <TransportHandler beanName="taxCalcWS"/>
      <DeadLetterDestination routeName="DeadLetter"/>
      <AuthConstraint principals="app-2"/>
   </Route>
   <Route name="RedeliveryRequest" retryPolicyRef="500-sec-retry">
      <TransportHandler beanName="redeliveryRequestJMSTransport"/>
      <DeadLetterDestination routeName="DeadLetter"/>
   </Route>
   <Route name="DeadLetter" retryPolicyRef="500-sec-retry">
      <TransportHandler beanName="deadLetterJMSTransport"/>
   </Route>
   <Route name="Redelivery" retryPolicyRef="500-sec-retry">
      <TransportHandler beanName="redeliveryJMSTransport"/>
      <DeadLetterDestination routeName="DeadLetter"/>
   </Route>
   <Route name="Error" retryPolicyRef="500-sec-retry">
      <TransportHandler beanName="errorJMSTransport"/>
   </Route>
   <Beans>
      <!-- Transport handlers for the service components. -->
      <Bean name="creditJMSTransport" className="org.bss.esb.transport.jms.JmsHandler">
         <Property name="ConnectionFactory" type="java.lang.String">
            <Value>qcf-1</Value>
         </Property>
         <Property name="Destination" type="java.lang.String">
            <Value>myCreditQueue</Value>
         </Property>
      </Bean>
      <Bean name="taxCalcWS" className="org.bss.esb.transport.webservice.WebServiceHandler">
         <Property name="WsdlUrl" type="java.lang.String">
            <Value>http://www.tax.com/calc</Value>
         </Property>
      </Bean>
      <!-- Transformer beans for the service components -->
      <Bean name="creditServiceTransform" className="org.bss.esb.transform.XSLTransform">
         <Property name="XslUrl" type="java.lang.String">
            <Value>file:///C:/temp/esb/transform/xsl/credit.xsl</Value>
         </Property>
      </Bean>
      <Bean name="taxCalcServiceTransform" className="org.bss.esb.transform.CustomTransform">
         <Property name="ConfigFileUrl" type="java.lang.String">
            <Value>file:///C:/temp/esb/transform/custom/configManager.properties</Value>
         </Property>
      </Bean>
      <!--  Transport handlers for the system queues -->
      <Bean name="redeliveryJMSTransport" className="org.bss.esb.transport.jms.JmsHandler">
         <Property name="ConnectionFactory" type="java.lang.String">
            <Value>qcf-1</Value>
         </Property>
         <Property name="Destination" type="java.lang.String">
            <Value>Redelivery.Queue</Value>
         </Property>
      </Bean>
      <Bean name="deadLetterJMSTransport" className="org.bss.esb.transport.jms.JmsHandler">
         <Property name="ConnectionFactory" type="java.lang.String">
            <Value>qcf-1</Value>
         </Property>
         <Property name="Destination" type="java.lang.String">
            <Value>System.DL.Queue</Value>
         </Property>
      </Bean>
      <Bean name="errorJMSTransport" className="org.bss.esb.transport.jms.JmsHandler">
         <Property name="ConnectionFactory" type="java.lang.String">
            <Value>qcf-1</Value>
         </Property>
         <Property name="Destination" type="java.lang.String">
            <Value>System.Error.Queue</Value>
         </Property>
      </Bean>
      <Bean name="redeliveryRequestJMSTransport" className="org.bss.esb.transport.jms.EsbRedeliveryHandler">
         <Property name="ConnectionFactory" type="java.lang.String">
            <Value>qcf-1</Value>
         </Property>
         <Property name="Destination" type="java.lang.String">
            <Value>Redelivery.Request.Topic</Value>
         </Property>
      </Bean>
   </Beans>
   <!-- Defines the retry policies that can be used by various route definitions. -->
   <RetryPolicies>
      <RetryPolicy name="100-sec-retry">
         <MaxRetries>10</MaxRetries>
         <RetryInterval>100</RetryInterval>
      </RetryPolicy>
      <RetryPolicy name="500-sec-retry">
         <MaxRetries>10</MaxRetries>
         <RetryInterval>500</RetryInterval>
      </RetryPolicy>
   </RetryPolicies>
</EsbConfiguration>

0
相关文章