• [SOA] Mule ESB 3.x 入门(一)—— 消息流


    关于Mule ESB,简单来说Mule接受一个消息,按照某种顺序处理这个消息,这样的处理可导致多种结果。有时,Mule改变或变换消息返回到原来的消息来源(request-response)。或者,在其原有的基础上改变形式发送到一个或多个第三方(router, transfer)。而在其他一些情况下,如果消息没有达到的具体要求,Mule可以拒绝处理的消息validation, throttling)。

    Mule 从3.0开始采用 flow 为单元的配置方式控制消息流(Mule 2.x 中使用 <service>),利用 Mule IDE 通过可视化的 flow blocks 来组装 flow。就像一个管道,消息从一端流向另一端。流动的消息,在 Mule 里被定义为 MuleMessage,它的结构就像下面这个样子:




    它由三大部分组成:1. header(消息头):按照范围划分的属性;2. payload(消息体);3. attachments(附件)。我们可以在 flow blocks 中,通过编程方式读取或者设置这些内容。在 Mule 开发中,会遇到一个概念:"transport barrier" (传输障碍)。比如:调用子流程没有“transport barrier",而跨端点则需要跨越"transport barrier"。其中,消息头的按照范围划分属性具有以下的特性:

    Mule Inbound Properties
    • Inbound Properties 是不能被修改的
    • Inbound Properties 由消息来源(如入站端点)设置
    • Inbound Properties 在跨越“transport barrier" 时丢失
    Mule Outbound Properties
    • Outbound Properties 可以被设置
    • 在跨越“交通障碍”,Outbound Properties自动变成Inbound Properties
    Mule Invocation Properties
    • Invocation Properties 可以被设置
    • Invocation Properties 在跨越“transport barrier" 时丢失
    Mule Session Properties
    • Session Properties 可以被设置
    • Session Properties 在跨越“transport barrier" 时仍然会保持
    Mule Flow Variable
    • 它们就像实例属性

    Mule Session Variable
    • 它们就像Session Properties
    根据上面的属性就可以知道 request 来的属性都存放在哪,response的属性应该如何控制。
    下面就是 Mule 开发中比较常见的一种 flow —— request-response


    一个简单的例子:通过 Http Endpoint 暴露出访问地址,客户端提交的请求经过 testFlow1 处理返回 response。中间记录一些log。

        <flow name="mule-maven-testFlow1" doc:name="mule-maven-testFlow1">
            <http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:8089/test" doc:name="HTTP"/>
            <logger message="#[headers:INBOUND:*]" level="INFO" doc:name="Logger Headers"/>
            <scripting:component doc:name="Groovy">
                <scripting:script engine="Groovy" file="scripts/build-response.groovy"/>
            </scripting:component>
            <logger message="#[groovy:message.toString()]" level="INFO" doc:name="Logger Message"/>
        </flow>
    首先用 logger component 记录一下请求的 header 信息,然后交给 groovy 构造 response 返回。
    def contentType = message.getInboundProperty("Content-Type");
    def response = "";
    if (contentType == "application/xml") {
    	response = "<string>hello world</string>"
    } else {
    	response = '{"string":"hello world"}'
    }
    
    response
    groovy脚本判断 request 的 content-type 如果是 application/xml 那么返回 xml 内容,如果是 application/json 那么返回 json 内容。

    通过 fiddler 模拟客户端对 http://localhost:8089/test  发送一个GET请求:
    通过 Mule IDE 控制台可以看到接收到的消息头内容:

    INFO  2013-08-11 23:08:50,473 [[mule-maven-test].connector.http.mule.default.receiver.03] org.mule.api.processor.LoggerMessageProcessor: {http.request=/test, Host=localhost:8089, http.method=GET, http.headers={Host=localhost:8089, User-Agent=Fiddler, Keep-Alive=false, Connection=false, Content-Type=application/xml}, http.relative.path=, User-Agent=Fiddler, http.request.path=/test, MULE_ORIGINATING_ENDPOINT=endpoint.http.localhost.8089.test, Connection=false, http.query.string=, http.context.path=/test, http.context.uri=http://localhost:8089/test, http.version=HTTP/1.1, http.query.params={}, MULE_REMOTE_CLIENT_ADDRESS=/0:0:0:0:0:0:0:1:24210, Keep-Alive=false, Content-Type=application/xml}

    随便说一下关于logger的写法:

    <logger message=" #[headers:INBOUND:*]" level="INFO" doc:name="Logger Headers"/>  输出所有的 inbound headers 属性(Map)
    <logger message=" #[headers:INBOUND:Host]" level="INFO" doc:name="Logger Header Property"/>  输出 inbound header 里的某一个属性
    <logger message=" #[groovy:message.getInboundProperty('Host')]" level="INFO" doc:name="Logger Host Value"/> 直接输出inbound property 里的某一属性的值
    <logger message=" #[groovy:message.toString()]" level="INFO" doc:name="Logger Message"/> 输出 Mule Message
    (注意:直接 #[groovy:message] 或者 #[message.toString()] 都不好使,那只会输出对象的引用地址)

    在多数场景下,直接输出 Mule Message 会更有跟踪价值,打印出来的 Mule Message 结构如下,你可以很清楚的观察到 Message 在 flow 里的变化。
    org.mule.DefaultMuleMessage
    {
      id=edced872-0297-11e3-ada6-610a86bd1f23
      payload=java.lang.String
      correlationId=<not set>
      correlationGroup=-1
      correlationSeq=-1
      encoding=UTF-8
      exceptionPayload=<not set>
    
    Message properties:
      INVOCATION scoped properties:
      INBOUND scoped properties:
        Connection=false
        Content-Type=application/xml
        Host=localhost:8089
        Keep-Alive=false
        MULE_ORIGINATING_ENDPOINT=endpoint.http.localhost.8089.test
        MULE_REMOTE_CLIENT_ADDRESS=/0:0:0:0:0:0:0:1:24210
        User-Agent=Fiddler
        http.context.path=/test
        http.context.uri=http://localhost:8089/test
        http.headers={Host=localhost:8089, User-Agent=Fiddler, Keep-Alive=false, Connection=false, Content-Type=application/xml}
        http.method=GET
        http.query.params={}
        http.query.string=
        http.relative.path=
        http.request=/test
        http.request.path=/test
        http.version=HTTP/1.1
      OUTBOUND scoped properties:
        MULE_ENCODING=UTF-8
      SESSION scoped properties:
    }
    再回头看看 fiddler 抓取的结果,就很容易明白 Inbound Properties, Outbound Properties, Payload 的关系了。










     
  • 相关阅读:
    网络基础知识-TCP/IP协议各层详解
    MySQL及其图形界面navicat的安装
    Python 浅谈编程规范和软件开发目录规范的重要性
    python 浅析模块,包及其相关用法
    spring batch中MyBatisPagingItemReader分页使用介绍
    eclipse中git插件使用
    oracle中查找某用户执行某张表的操作操作记录
    redis集群主流架构方案分析
    消息队列常见的 5 个应用场景
    Kafka vs RocketMQ——单机系统可靠性
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3253826.html
Copyright © 2020-2023  润新知