24、企业服务总线(ESB)中的企业集成模式

ESB中的企业集成模式介绍

企业服务总线(ESB)中的企业集成模式

在企业集成领域,ESB(企业服务总线)是实现系统间高效通信和数据交换的关键技术。本文将详细介绍ESB中的几种重要集成模式,包括追踪组件、消息过滤器、拆分聚合器和管道,并提供相应的示例代码和配置。

1. 追踪组件(Trace Component)

追踪组件参与仅入(In-Only)消息交换模式(MEP),并将消息打印到控制台。以下是在 servicemix.xml 文件中配置追踪组件及相关组件的示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer"
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
   <sm:activationSpecs>
      <sm:activationSpec componentName="httpReceiver" 
                         service="test:httpBinding"
                         endpoint="httpReceiver"
                         destinationService="test:wireTap">
         <sm:component>
            <bean class="org.apache.servicemix.components.http.HttpConnector">
               <property name="host" value="localhost"/>
               <property name="port" value="8912"/>
            </bean>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="echo" service="test:echo">
         <sm:component>
            <bean class="org.apache.servicemix.components.util.EchoComponent" />
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="trace" service="test:trace">
         <sm:component>
            <bean class="org.apache.servicemix.components.util.TraceComponent" />
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:wire-tap service="test:wireTap" 
                                endpoint="wireTapEndpoint">
                     <eip:target>
                        <eip:exchange-target service="test:echo" />
                     </eip:target>
                     <eip:inListener>
                        <eip:exchange-target service="test:trace" />
                     </eip:inListener>
                  </eip:wire-tap>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
</beans>

在上述配置中, test:echo test:trace 被配置为消息交换的监听器,因此消息将被转发到这两个组件。

部署和运行示例
  1. 切换到 ch15\05_WireTap 目录并执行 ant 命令:
cd ch15\05_WireTap
ant

此命令将编译所有文件,包括HTTP客户端程序。
2. 启动ServiceMix:

cd ch15\05_WireTap
%SERVICEMIX_HOME%\bin\servicemix servicemix.xml
  1. 在另一个命令提示符中执行 ant run
cd ch15\05_WireTap
ant run

HTTP客户端程序将向ESB中配置的HTTP连接器发送测试XML消息。在ESB控制台中,我们可以验证消息是否已传递到 test:echo test:trace 服务。HTTP客户端还将打印从ESB接收到的响应。

2. 消息过滤器(Message Filter)

消息过滤器可以从发布的一组消息中消除不需要的消息。其工作原理是根据消息内容匹配过滤规则,匹配的消息将被路由到输出通道,不匹配的消息将被忽略。

示例设计

假设Acme公司决定为所有单次结账金额超过一定数量的订单提供折扣和礼品。可以使用窃听器将所有订单的副本发送到消息过滤器,过滤器将检查消息中的结账总金额,如果超过阈值,则将消息转发到优惠管理模块;否则,消息将被丢弃。

示例用例组件
  • JMS客户端 :一个普通的外部JMS客户端,将XML消息发送到ESB中配置的JMS消费者组件。
  • JMS消费者 servicemix-jms 监听队列 “A”,将接收到的消息路由到消息过滤器。
  • 消息过滤器 servicemix-eip 组件,使用XPath谓词定义过滤规则,匹配的消息将被转发到接收组件,不匹配的消息将被丢弃。
  • 接收组件 :将接收到的消息打印到控制台。
示例代码和配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
   <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:MyConsumerService"
                                endpoint="myConsumer"
                                role="consumer" 
                                soap="false" 
                                targetService="test:messageFilter" 
                                defaultMep="http://www.w3.org/2004/08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/A"
                                connectionFactory  = "#connectionFactory" />
               </jms:endpoints>
            </jms:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="receiver" 
                         service="test:receiver">
         <sm:component>
            <bean xmlns="http://xbean.org/schemas/spring/1.0" 
                  class="MyReceiver" >
               <property name="name">
                  <value>1</value>
               </property>
            </bean>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
              <eip:endpoints>
                <eip:message-filter service="test:messageFilter" 
                                    endpoint="messageFilterEndpoint">
                    <eip:target>
                       <eip:exchange-target 
                           service="test:receiver" />
                     </eip:target>
                     <eip:filter>
                        <eip:xpath-predicate 
                           xpath="/hello/@id = '1'"/>
                     </eip:filter>
                  </eip:message-filter>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container> 
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>

上述代码中,过滤规则为 XPath "/hello/@id = '1'"

部署和运行示例
  1. 切换到 ch15\06_MessageFilter 目录并执行 ant 命令:
cd ch15\06_MessageFilter
ant

此命令将编译所有文件,包括JMS客户端程序。
2. 启动ServiceMix:

cd ch15\06_MessageFilter
%SERVICEMIX_HOME%\bin\servicemix servicemix.xml
  1. 在另一个命令提示符中执行 ant run
cd ch15\06_MessageFilter
ant run

JMS客户端程序将打印发送到ESB的消息。在ESB控制台中,我们可以看到只有匹配过滤规则的消息被转发到接收组件,其他消息被丢弃。

3. 拆分聚合器(Split Aggregator)

聚合器是一种有状态的过滤器,可以存储通过某种ID或字段关联的消息部分。当所有部分都准备好时,它可以将所有部分聚合为一个单一的聚合消息。

示例设计

在Acme后端系统中,每个完整订单在确认之前需要与可用库存进行验证。我们将订单拆分为订单项目,并将每个项目的消息发送到不同的库存模块。在返回订单验证消息给客户之前,需要检查每个订单项目的验证状态。可以使用聚合器来接收所有相关订单项目的状态消息,当接收到所有消息后,评估整体状态并返回决策(确认订单或错误)。

示例用例组件
  • 默认ServiceMix客户端 :发送多个仅入消息到ESB中配置的拆分聚合器,每个消息都有关联ID,并携带 splitCount splitIndex
  • 拆分聚合器 servicemix-eip 组件,根据关联ID、 splitCount splitIndex 对消息进行重新排序和聚合,当所有部分都到达时,将聚合消息转发到追踪组件。
  • 追踪组件 :将从拆分聚合器接收到的聚合消息打印到ESB控制台。
示例代码和配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container id="jbi" 
                 monitorInstallationDirectory="false"
                 createMBeanServer="false"
                 useMBeanServer="false">
   <sm:activationSpecs>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:split-aggregator service="test:aggregator" 
                                        endpoint="aggregatorEndpoint"
                                        aggregateElementName=
                                           "test:MessageEnvelope"
                                        messageElementName=
                                           "test:MessagePart">
                     <eip:target>
                        <eip:exchange-target service="test:trace" />
                     </eip:target>
                  </eip:split-aggregator>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="trace" service="test:trace">
         <sm:component>
            <bean class="org.apache.servicemix.components.util.TraceComponent" />
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
   <bean id="client" class="org.apache.servicemix.client.DefaultServiceMixClient">
      <constructor-arg ref="jbi"/>
   </bean>
</beans>

拆分聚合器配置了 aggregateElementName messageElementName ,用于决定聚合消息时使用的消息信封。

部署和运行示例
  1. 切换到 ch15\07_SplitAggregator 目录并执行 ant 命令:
cd ch15\07_SplitAggregator
ant

此命令将编译所有文件。
2. 执行 ant run 测试示例:

cd ch15\07_SplitAggregator
ant run

在ESB控制台中,我们可以看到消息被发送到聚合器,最终聚合器将所有相关消息组合并转发到追踪组件,追踪组件将消息打印到控制台。

4. 管道(Pipeline)

管道是一种可以将一种消息交换模式(MEP)转换为另一种模式的桥梁。它可以将仅入MEP转换为入出MEP,然后将转换后的消息发送到转换器组件,转换器组件返回的响应将以另一种仅入MEP转发到管道目标。

示例设计

Acme电子商务系统允许客户在线支付,每个支付消息需要安全可靠地路由到金融机构的系统。金融机构的支付服务是一个请求 - 响应式的HTTP服务,而JMS使用仅入MEP,因此需要使用管道在JMS和HTTP协议之间建立桥梁。

示例用例组件
  • JMS客户端 :将XML消息发送到ESB中配置的JMS消费者组件。
  • JMS消费者 servicemix-jms 监听队列 “A”,将接收到的消息路由到管道。
  • 管道 servicemix-eip 组件,将从JMS消费者接收到的仅入MEP消息转换为入出MEP消息发送到回声组件,回声组件的响应将以另一种仅入MEP转发到JMS消费者。
  • 回声组件 :将接收到的消息原样返回给管道。
  • JMS提供者 servicemix-jms 监听队列 “B”,管道将回声响应消息放入此队列,JMS客户端可以从中获取消息。

综上所述,这些企业集成模式在ESB中发挥着重要作用,通过合理配置和使用这些模式,可以实现系统间的高效通信和数据交换。在实际应用中,我们可以根据具体需求选择合适的模式,并按照上述步骤进行部署和测试。

企业服务总线(ESB)中的企业集成模式

示例代码和配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xbean.org/schemas/spring/1.0" 
       xmlns:sm="http://servicemix.apache.org/config/1.0"
       xmlns:test="http://xslt.servicemix.apache.binildas.com" 
       xmlns:eip="http://servicemix.apache.org/eip/1.0" 
       xmlns:jms="http://servicemix.apache.org/jms/1.0">
   <classpath>
      <location>.</location>
   </classpath>
   <import resource="classpath:jmx.xml" />
   <import resource="classpath:jndi.xml" />
   <import resource="classpath:security.xml" />
   <import resource="classpath:tx.xml" />
   <import resource="classpath:activemq.xml" />
   <bean id="propertyConfigurer" 
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="location" 
                value="classpath:servicemix.properties" />
   </bean>
   <sm:container name="jbi"
                 monitorInstallationDirectory="false"
                 createMBeanServer="true"
                 useMBeanServer="true">
   <sm:activationSpecs>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:MyConsumerService"
                                endpoint="myConsumer"
                                role="consumer" 
                                soap="false" 
                                targetService="test:pipeline" 
                                defaultMep="http://www.w3.org/2004/08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/A"
                                connectionFactory  = "#connectionFactory" />
               </jms:endpoints>
            </jms:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec componentName="echo" service="test:echo">
         <sm:component>
            <bean class="org.apache.servicemix.components.util.EchoComponent" />
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec id="servicemix-eip">
         <sm:component>
            <eip:component>
               <eip:endpoints>
                  <eip:pipeline service="test:pipeline" 
                                endpoint="pipelineEndpoint">
                     <eip:target>
                        <eip:exchange-target service="test:jmsProvider" />
                     </eip:target>
                     <eip:transformer>
                        <eip:exchange-target service="test:echo" />
                     </eip:transformer>
                  </eip:pipeline>
               </eip:endpoints>
            </eip:component>
         </sm:component>
      </sm:activationSpec>
      <sm:activationSpec>
         <sm:component>
            <jms:component>
               <jms:endpoints>
                  <jms:endpoint service="test:jmsProvider"
                                endpoint="jmsProvider"
                                role="provider" 
                                soap="false" 
                                sourceService="test:pipeline" 
                                defaultMep="http://www.w3.org/2004/08/wsdl/in-only"
                                destinationStyle="queue"
                                jmsProviderDestinationName="queue/B"
                                connectionFactory  = "#connectionFactory" />
               </jms:endpoints>
            </jms:component>
         </sm:component>
      </sm:activationSpec>
   </sm:activationSpecs>
   </sm:container>
   <bean id="connectionFactory" 
         class="org.apache.activemq.ActiveMQConnectionFactory">
      <property name="brokerURL" value="tcp://localhost:61616" />
   </bean>
</beans>
部署和运行示例
  1. 切换到相应目录并编译文件:
cd ch15\08_Pipeline
ant

此步骤会编译所有相关文件。
2. 启动ServiceMix:

cd ch15\08_Pipeline
%SERVICEMIX_HOME%\bin\servicemix servicemix.xml
  1. 在另一个命令提示符中执行测试:
cd ch15\08_Pipeline
ant run

JMS客户端发送消息到ESB后,经过管道的MEP转换和回声组件的处理,最终回声响应消息会被放入队列 “B”,JMS客户端可以从该队列获取消息。

总结

本文介绍了ESB中的几种重要企业集成模式,下面通过表格进行总结:
| 集成模式 | 功能 | 示例用例组件 | 关键配置 |
| — | — | — | — |
| 追踪组件 | 参与仅入MEP并在控制台打印消息 | httpReceiver、echo、trace等 | 在 servicemix.xml 中配置相关组件和监听器 |
| 消息过滤器 | 消除不需要的消息 | JMS客户端、JMS消费者、消息过滤器、接收组件 | 使用XPath谓词定义过滤规则 |
| 拆分聚合器 | 存储关联消息部分并聚合为单一消息 | 默认ServiceMix客户端、拆分聚合器、追踪组件 | 配置 aggregateElementName messageElementName |
| 管道 | 转换MEP | JMS客户端、JMS消费者、管道、回声组件、JMS提供者 | 在 servicemix.xml 中配置管道和相关端点 |

流程图示例

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A([JMS客户端]):::startend -->|发送消息| B(JMS消费者):::process
    B -->|路由消息| C(管道):::process
    C -->|转换MEP| D(回声组件):::process
    D -->|返回响应| C
    C -->|转发消息| E(JMS提供者):::process
    E -->|消息放入队列B| F([JMS客户端]):::startend

通过合理运用这些集成模式,可以有效提升企业系统间的通信效率和数据交换能力,满足不同业务场景的需求。在实际开发中,开发者可以根据具体业务需求选择合适的集成模式,并按照示例代码和部署步骤进行实现和测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值