mule in action翻译10 : 2.2 和消息交互

mule in action翻译10 :  2.2 和消息交互

 

 2.2 和消息交互

 mule支持几种交互方式,交互的结果是创建新的消息或者是处理一个已经存在的消息。

 先学习消息交互中非常重要的术语:

 Receiving-- 接收  : 发生在消息源处,当一个外部的事件发生时

                                (比如一个HTTP请求 或来自JMS的消息),将产生一个新的mule消息。

 Polling-- 轮询:          也发生消息源处,mule主动发起的,以一个特定的频率发生,也会生成新的mule消息。

 Dispatching--分发:发生在消息处理器处,mule向外发出消息后不会等待响应。

 Sending--发送:     发生在消息处理器处,mule发出消息后会等待同步响应。

                                 这个响应会产生一个新的mule消息。

 Requesting--请求:以编程的方式发生,从某个源取回数据后会生成新的mule消息

                               (例如从读入某个文件的内容或消费JMS队列的消息)

 对这些交互方式的支持 依赖于mule的一些核心概念,这实际是其它消息处理的基础。

 本部分学习下列概念:

 消息源

 消息处理器

 消息交换方式

 Endpoint URIs

 2.2.1 消息源

 在mule配置中消息源一般也作为接入端口( inbound endpoints)。轮询器一般也会使用消息源。

 云连接器也会提供消息源,并可用在配置文件中。

 一个流中只能有一个消息源。为了从多个接入端口生成消息,必须使用复合消息源。

 复合消息源当然也是一个消息源。下面列表展示了一些有效的消息源,其中就有复合消息源

 Listing 2.7 Simple and composite message sources

 <vm:inbound-endpoint path="payment-processor" />
<composite-source>
       <jms:inbound-endpoint queue="payment-processor" />
      <http:inbound-endpoint host="localhost" port="8080" path="payment-processor" />
</composite-source>

复合消息源:  复合消息源的每个端口(endpoint)当收到消息后将会启动一个新的执行流。

                      复合消息源不限制传输协议,不限制交互方式。

2.2.2 消息处理器

  消息处理器是mule配置的基本构成模块。除了消息源,流基本上都是有消息处理器组成。

  消息处理器执行mule中所有的消息处理操作,在而配置文件中消息处理器有多种元素。

  

  消息处理器的主要功能:

  1、 作为 接出端口(outbound endpoints ),分发消息到目的地。

  2、 作为 转换器(transformers) ,能够修改消息。

  3、 作为 路由器(routers),保证把消息发送到正确目的地。

  4、 作为 组件(components),执行对消息的业务操作。

  

 多数时候,你只需要配置信息处理器。你配置文件中看到的转换器、组件、端口都是消息处理器。

 实际上多样的消息处理器是mule实现功能多样性的关键。你可以在配置文件中自由的组合他们。

 各种消息处理器实质上是相同的,他们是可以互换的。

 把消息处理器硬塞进一个链  当本地配置文件只允许一个消息处理器时,

可以使用 processor-chain 元素,这个处理器封装了多个按顺序被调用的消息处理器(就像一个链一样)

 

 实现org.mule.api.processor.MessageProcessor,可以创建客户化的消息处理器,并可配置在配置文件中。

  这非常有用,代价是要直接暴露给mule内部构件。

  

 2.2.3 消息交换方式

  消息交换方式(Message exchange patterns--MEP),描述接入端口和接出端口的连接方式。

  通过定义端口交互是同步的还是异步的,MEP会影响端口的两边

(发送者和接收者,或者说是客户端和服务端)

  当前mule只支持两种 MEP:

  1、One-way  单向式, 此交互不需要返回同步的响应。

  2、Request-response 请求-响应式,需要返回同步的响应。

  

  两种MEP都可以用在接入端口和接出端口,但一些传输协议可能会限制交换方式(比如POP3是单向的)。

  在接入端口,单向式意味着mule不必给调用者返回响应,而请求-响应式则需返回。

  在接出端口,单向式意味着mule不必等待被调用者返回响应,即使返回响应也会被忽略掉,

                       而请求-响应式则需等待响应。

  说些别的   当客户端调用了一个单向式服务后,将会阻塞住并等待响应,它将收到一个空的响应。

                   例如向一个in-only  HTTP 接入端口发送GET请求,将收到空的响应(内容长度是0)

                   和一个200 ok 的状态码。

                   需要注意的例外是 VM的transport;客户端和服务端都必须同意其交换方式否则消息交换会失败。

    不要把单向式和 fire-and-forget混为一谈。mule保证消息得到正确传递。

    例如,当向单向式JMS端口( JMS endpoint)

    分发消息时,mule会保证消息得到可靠的传送,否则会抛出异常。这同样适用于单向式的HTTP端口,

   其与request-response的最大的不同是 当mule只收到响应的状态码就行了不管其他的了。

   --收到响应码表示对方成功接收。

举例说明,看列表2.8中的两个不同的HTTP endpoints ,

各自的MEP不同(通过 exchange-pattern属性配置)。

接入端口使用request-response MEP,它将提供同步的响应给发送HTTP请求的客户端。

接出端口是one-way,意味着mule(作为客户端)将不会等待远程服务器的响应,

不管服务端是否返回了响应。

Listing 2.8 HTTP endpoints with different exchange patterns

<http:inbound-endpoint host="localhost" port="8080"
                                       path="payment-processor"
                                       exchange-pattern="request-response" />
<http:outbound-endpoint host="localhost" port="8081"
                                         path="notifier"
                                         exchange-pattern="one-way" />

MEP  影响了消息交互的时间轴;equest-response是时间上紧密连接的,而one-way避免了这种情况。

MEP 会直接严重影响mule的并发处理,当高并发时,流的执行会出现难以预料的情况。

看下面配置:

Listing 2.9 A simple flow in which execution doesn’t happen as expected

<flow name="acmeApiBridge">
    <vm:inbound-endpoint path="invokeAcmeAmi" />
    <jdbc:outbound-endpoint queryKey="storeData" />
    <http:outbound-endpoint address="http://acme.com/api" />
</flow>

Prancing Donkey 公司使用这个配置把HTTP会话状态保存到数据库。

当建立一个连接 Acme Corp API 的新会话时会使用到这个流。

在另一个流中,HTTP的响应会进一步修改会话的状态。

这个流中不时的出现HTTP请求在 JDBC 完成insert前被分发出去的现象,

可是在配置文件中jdbc 明明是在http之前啊,这真是让人困惑。

这怎么可能?

看一下日志记录:

DEBUG acmeApiBridge.stage1.02 [HttpConnector]

Borrowing a dispatcher for endpoint: http://acme.com/api

INFO jdbcConnector.dispatcher.01 [SimpleUpdateSqlStatementStrategy]

Executing SQL statement: 1 row(s) updated

DEBUG acmeApiBridge.stage1.02 [HttpClientMessageDispatcher]

Connecting: HttpClientMessageDispatcher{this=1e492d8,

endpoint=http://acme.com/api, disposed=false}

注意线程的名字(在日志级别和类名之间的方括号内)。

你看到什么? 你发现JDBC insert是被一个主线程之外的独立线程执行的。

为什么mule使用一个单独的线程执行jdbc操作?

答案关键在于每个 endpoint使用的消息交换方式。

注意上面的这个流没有指定消息交换方式,这会使用默认的交换方式:

jdbc是one-way的,HTTP是request-response的。

因为是one-way的,mule知道不用期待返回响应,所以才使用一个单独的线程处理。

图2.6 说明了one-way 的MEP如何进行并行处理。

在5.3.3节,我们再看其它的进行消息并行处理的方式。



 

不要玩猜字游戏  要是你的流清晰明了,不要依赖于默认设置,要在你的endpoints中使用显示的 MEP配置。

 

2.2.4 Endpoint URIs

     mule使用统一资源标示符(URI) 作为他对外暴露的或是通过endpoints访问的资源的统一的表示。

换句话说,inbound和outbound在内部使用URI进行配置。

在xml配置文件中他们由不同的元素、不同的属性进行配置。

实际上,这些不同元素不同属性的配置最后都将组合成一个endpoint URI。

看下例。 URI用来表示HTTP资源大家很熟悉了,请注意JMS和TCP怎配置的。

    http://localhost:8080/products

    jms:topic://news

    tcp://localhost:51000?connector=pollingTcpConnector

完整的如列表2.10 ,展示了mule使用URI暴露资源的配置。

Listing 2.10 Mule endpoints exposing different types of resources

<http:inbound-endpoint host="localhost" port="8080" path="products" />
<jms:inbound-endpoint topic="news" />
<tcp:inbound-endpoint host="localhost" port="51000" connector-ref="pollingTcpConnector" />

猜你喜欢

转载自yangzhonglei.iteye.com/blog/2089585