本篇主要介绍在Mule ESB中控制消息的流向。控制消息的流向有很多不同的场景,数据的路由,数据的拆分和组合,数据的排序,数据的分发等。数据路由是ESB平台上最基本,也是最重要的功能之一,完整的ESB平台都会有相对应的功能。ESB基本的功能可分成消息路由,消息传输和消息转换等,后续几篇Mule ESB开发教程我们会陆续讲解这些功能。

Mule ESB同样具有很多的消息路由组件。作为开源ESB产品中很成熟的平台,Mule ESB的发展状态非常好,经过多年的发展,2017年在纽交所成功上市。Mule ESB拥有众多的企业案例,我们作为MuleSoft的重要合作伙伴,使用Mule ESB企业版开发实施,或者Mule ESB社区版开发实施,帮助国内众多的行业标杆客户成功上线企业集成项目。

Mule ESB的源代码托管在GitHub上,拥有非常详细的英文文档,Mule ESB的中文文档资料和开发教程却非常少,我们使用8篇文章来写基础Mule ESB中文开发教程,一起为开源软件做贡献。

1. 使用场景

我们来看一个常见的应用场景。我们的集成应用可以接收客户端提交订单的请求,有多种不同类型的客户端。手机客户端是一个App,我们在App上使用的消息格式通常是轻量级的JSON格式。而PC客户端是一个Windows时代的产物,它仍然使用XML格式。我们的集成应用在接收到订单请求后,会根据订单的类别分发到不同的仓库,订单类别存储在订单内容的OrderType字段中。

2. 基于消息头的路由

我们首先要区分订单的格式,因为JSON和XML的处理逻辑是完全不同的。在Mule中我们可以使用MEL的JSON Path来解决JSON文件的解析,XML Path来解决XML文件的解析。MEL的详细用法可以参考上一篇文章。订单的格式通常会放在消息头上传递,而Mule Message中对应消息头的部分就是Message Inboud Properties。

2.1 使用JSON提交订单的消息

{
"OrderType": "Book",
"TotalAmount": 1000,
"OrderLines": [{
"ProductName": "Learn English",
"Qty": 3,
"Price": 300
}, {
"ProductName": "Lean Mule ESB",
"Qty": 1,
"Price": 100
}]
}

使用Postman提交JSON,注意Content-Type设置为application/json。

通过Postman的Preview可以看到,实际上Http的Request头信息上设定了Content-Type字段为application/json。

2.2 使用XML提交订单的消息

<?xml version="1.0" encoding="UTF-8"?>
<OrderInfo>
<OrderType>Book</OrderType>
<TotalAmount>1000</TotalAmount>
<OrderLines>
<OrderLine>
<ProductName>Learn English</ProductName>
<Qty>3</Qty>
<Price>300</Price>
</OrderLine>
<OrderLine>
<ProductName>Learn Mule ESB</ProductName>
<Qty>1</Qty>
<Price>100</Price>
</OrderLine>
</OrderLines>
</OrderInfo>

使用Postman提交XML,注意Content-Type设置为application/xml。

通过Postman的Preview可以看到,实际上Http的Request头信息上设定了Content-Type字段为application/xml。

2.3 使用Choice组件判断订单格式

Mule ESB最基本的路由组件就是Choice组件,组件类似于我们在编程语言中的if/esle if/else。订单的格式是存放在Message Inbound Properties中的。这里就使用Choice组件来判断订单的格式。

Mule XML Config:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="flow-control">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['content-type'] == 'application/json']">
<logger message="JSON" level="INFO" doc:name="JSON"/>
</when>
<when expression="#[message.inboundProperties['content-type'] == 'application/xml']">
<logger message="XML" level="INFO" doc:name="XML"/>
</when>
<otherwise>
<logger message="Error" level="INFO" doc:name="Error"/>
</otherwise>
</choice>
</flow>
</mule>

Mule UI Config:

通过Choice组件所支持的MEL语法,我们就能通过判断mule message inboundProperties来确定订单格式。需要注意的是,图上所示的Default是选择的最后一个路径,实际是if,else if,else,end if这个路径中的else路径。

3. 基于消息内容的路由

通过消息头的判断,我们已经可以区分JSON格式和XML格式订单,那么如果区分订单类型呢,这里就需要用到基于消息内容的路由,我们对前面的代码做改进,同时引入消息队列。

Mule XML Config:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:jms="http://www.mulesoft.org/schema/mule/jms" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<jms:activemq-connector name="Active_MQ" brokerURL="tcp://192.168.63.1:61616" validateConnections="true" doc:name="Active MQ"/>
<flow name="flow-control">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['content-type'] == 'application/json']">
<set-variable doc:name="orderType" value="#[json:/OrderType]" variableName="orderType"/>
<choice doc:name="Choice">
<when expression="#[flowVars.orderType == 'Book']">
<jms:outbound-endpoint queue="bookQ" connector-ref="Active_MQ" doc:name="bookQ"/>
</when>
<when expression="#[flowVars.orderType == 'Tool']">
<jms:outbound-endpoint queue="toolQ" connector-ref="Active_MQ" doc:name="toolQ"/>
</when>
<otherwise>
<jms:outbound-endpoint queue="DLQ" connector-ref="Active_MQ" doc:name="DLQ"/>
</otherwise>
</choice>
</when>
<when expression="#[message.inboundProperties['content-type'] == 'application/xml']">
<set-variable doc:name="orderType" value="#[xpath://OrderInfo/OrderType]" variableName="orderType"/>
<choice doc:name="Choice">
<when expression="#[flowVars.orderType == 'Book']">
<jms:outbound-endpoint queue="bookQ" connector-ref="Active_MQ" doc:name="bookQ"/>
</when>
<when expression="#[flowVars.orderType == 'Tool']">
<jms:outbound-endpoint queue="toolQ" connector-ref="Active_MQ" doc:name="toolQ"/>
</when>
<otherwise>
<jms:outbound-endpoint queue="DLQ" connector-ref="Active_MQ" doc:name="DLQ"/>
</otherwise>
</choice>
</when>
<otherwise>
<jms:outbound-endpoint queue="DLQ" connector-ref="Active_MQ" doc:name="DQL"/>
</otherwise>
</choice>
</flow>
</mule>

Mule UI Config:

4. 其他控制流向的组件

除了使用Choice组件改变Flow执行路径以外,还要很多控制流向的组件。比如Round-Robin,Resequencer,Scatter-Gather,Splitter,Aggregator等组件。这些组件的用法各不相同,这里主要讲一下Round-Robin的用法。Round-Robin是一种轮询调度算法,在负载均衡的策略里面经常见到Round-Robin,轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。

Mule的Round-Robin组件也是类似的思路,轮询执行Flow中的分支路径。举例如下,我们接收到用户的检索请求,每次请求我们使用不同的执行路径,第一次使用Bing搜索,第二次使用Google,第三次使用Baidu。

Mule XML Config:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="round-robin-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<round-robin doc:name="Round Robin">
<set-payload value="Baidu" doc:name="Baidu"/>
<set-payload value="Google" doc:name="Google"/>
<set-payload value="Bing" doc:name="Bing"/>
</round-robin>
</flow>
</mule>

Mule UI Config:

本文同步发文于EnjoyingSoft BlogsCSDN简书

访问EnjoyingSoft 网站,获取更多Mule ESB 社区版 实施帮助。

欢迎转载,但必须保留原文和此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

EnjoyingSoft之Mule ESB开发教程系列第五篇:控制消息的流向-数据路由的更多相关文章

  1. EnjoyingSoft之Mule ESB开发教程第一篇:初识Mule ESB

    目录 1. Mule ESB基本介绍 2. Mule ESB社区版和企业版 3. Mule ESB常用场景 4. Mule ESB软件安装 客户端安装 服务端安装 5. 第一个Mule ESB应用- ...

  2. EnjoyingSoft之Mule ESB开发教程第二篇:Mule ESB基本概念

    目录 1. 使用Anypoint Studio开发 2. Mule ESB Application Structure - Mule ESB应用程序结构 3. Mule ESB Application ...

  3. EnjoyingSoft之Mule ESB开发教程第三篇:Mule message structure - Mule message结构

    目录 1. 探索Mule Message结构 2. Mule Message的Payload 3. Mule Message的Property 4. Mule Message的Attachment 5 ...

  4. EnjoyingSoft之Mule ESB开发教程第四篇:Mule Expression Language - MEL表达式

    目录 1. MEL的优势 2. MEL的使用场景 3. MEL的示例 4. MEL的上下文对象 5. MEL的Variable 6. MEL访问属性 7. MEL操作符 本篇主要介绍Mule表达式语言 ...

  5. EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换

    目录 1. 数据转换概念 2. 数据智能感知 - DataSense 3. 简单数据转换组件 3.1 Object to JSON 3.2 JSON to XML 3.3 JSON to Object ...

  6. Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密

    前不久,微信的企业号使用了强制的消息加密方式,随后公众号也加入了可选的消息加密选项.目前企业号和公众号的加密方式是一致的(格式会有少许差别). 加密设置 进入公众号后台的“开发者中心”,我们可以看到U ...

  7. MongoDB基础教程系列--第五篇 MongoDB 映射与限制记录

    上一篇提到的 find() 的方法,细心的伙伴会发现查询的结果都是显示了集合中全部的字段,实际应用中,显然是不够用的.那么有没有办法指定特定的字段显示出文档呢?答案是肯定的,MongoDB 中用映射实 ...

  8. iOS 11开发教程(十五)iOS11应用视图的位置和大小

    iOS 11开发教程(十五)iOS11应用视图的位置和大小 当一个视图使用拖动的方式添加到主视图后,它的位置和大小可以使用拖动的方式进行设置,也可以使用尺寸检查器面板中的内容进行设置,如图1.52所示 ...

  9. struts2官方 中文教程 系列十二:控制标签

    介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...

随机推荐

  1. Oracle序列使用:建立、删除、使用

    Oracle序列使用:建立.删除 在开始讲解Oracle序列使用方法之前,先加一点关于Oracle client sqlplus的使用,就是如果执行多行语句的话一定要加“/”才能表示结束,并执行!本篇 ...

  2. QQ邮箱打败163邮箱的过程(重视用户体验的结果)

    引用 楼主 CKAOS 的回复: 目前负责一个项目,ASP.NET的,做一个网盘系统,别的都弄好了,只差一个下载文件夹的功能未实现,只能在服务器端打包成压缩文件,再发回浏览器.如何直接下载文件夹,不是 ...

  3. 【Linux】Linux相关资料

    linux相关技术资料: linux技术资料大全: http://t.cn/zYNBwFs

  4. Python自动化测试 (八)unittest 单元测试

    任何一种编程语言, 都会有单元测试框架, 本文介绍Python 自带的unittest模块 # -* - coding: UTF- -* - class Myclass: def sum(self,x ...

  5. centos yum 安装 jdk1.8

    JDK: 版本:1.8 服务器默认安装1.7,所以不使用默认安装 yum -y list java* --查看yum的jdk安装包 yum install java-1.8.0-openjdk jav ...

  6. Cleanmymac X 4.4.3 激活破解版|兼容mac最新系统-Mac电脑清理工具

    CleanMyMac X 4.4.3 激活破解版为最新版清理工具,为你所爱的东西腾出空间.CleanMyMac拥有一系列巧妙的新功能,它可以安全.智能地扫描和清理整个系统,删除大的未使用的文件,卸载不 ...

  7. linux下安装Nginx1.16.0

    因为最近在倒腾linux,想安装新版本的nginx,找了一圈教程没有找到对应的教程,在稍微倒腾了一会之后终于成功的安装了最新版. 服务器环境为centos,接下来是详细步骤: 安装必要依赖插件 yum ...

  8. LVS-DR模式部署流程

    情景一 一.环境介绍 1)RIP.VIP.DIP为同一物理网络 2)LVS Hostname:lvs eth0:DIP-192.168.3.31 eth0:0:VIP-192.168.3.10 3)R ...

  9. iOS登录及token的业务逻辑(没怎么用过,看各种文章总结)

    http:是短连接. 服务器如何判断当前用户是否登录? // 1. 如果是即时通信类:长连接. // 如何保证服务器跟客户端保持长连接状态? // "心跳包" 用来检测用户是否在线 ...

  10. Zookeeper详解-Cli(五)

    ZooKeeper命令行界面(CLI)用于与ZooKeeper集合进行交互以进行开发.它有助于调试和解决不同的选项. 要执行ZooKeeper CLI操作,首先打开ZooKeeper服务器(“bin/ ...