[SOA] Mule ESB 3.x 入门(三)—— 消息路由

来源:互联网 发布:日本高考数学试题 知乎 编辑:程序博客网 时间:2024/04/29 10:53
在前面两篇博文基础上,继续来看看如何利用 Mule 来实现简单的消息路由。消息路由是ESB平台上最基本最重要的功能,它是指通过一定的规则将消息从一个端点发送到另一端点。通常ESB平台上会统一管理很多服务,为了便于使用和管理通常会对外暴露一个唯一入口,通过请求携带的路由信息来进行分发。

如下图所示:

ESB平台将维护一套路由表,根据请求中的路由信息来做处理。这个路由信息就是指在路由表中能唯一识别真实服务信息(数据)的相关数据(key),利用Mule Message我们可以在以下几个地方做功课。

1. 利用Http Header 来传送路由信息
在 Http Header 中添加自定义信息,ESB平台根据Header的数据进行处理。
这种方式实施比较简单,接入方需要修改一点代码即再调用HttpRequest之前需要按照约定封装Header。
OAuth 认证也是通过Header携带Auth信息来做的。

2. 利用URL来传送路由信息
通过 QueryString(或者是rest风格的URL) 传递信息,这种方式实施更简单,接入方甚至无须直接修改代码改改配置文件的URL即可。
但通过QueryString传递数据比较暴露而且有长度限制。

3. 利用Http Body 来传送路由信息
将路由信息存放在 Http Body里,这种方式实施比较麻烦,接入方需要修改不少代码而且极不灵活。
需要整体规划,将报文格式全部统一下来。

接下来举个栗子,看看 Mule 3.x 如何实现消息路由的(方式2)。
实现方式2——根据URL路由信息处理,核心很简单,通过一个groovy 脚本来处理(Mule 自带Choose组件,但还是自己写脚本灵活)

import org.apache.log4j.*;Logger logger = LogManager.getLogger("router");class Router implements Serializable {def serviceId, address, contentType} List routers = [new Router(serviceId:"svc001", address:"localhost:11788/Service1.svc"),new Router(serviceId:"svc002", address:"localhost:11789/Service1.svc"),new Router(serviceId:"svc003", address:"localhost:11790/Service1.svc"),new Router(serviceId:"svc004", address:"localhost:11791/Service1.svc"),];def requestSvcId = message.getInboundProperty("http.relative.path");logger.info "======== request serviceId: ${requestSvcId}"def requestContentType = message.getInboundProperty("Content-Type");logger.info "======== request contentType: ${requestContentType}"message.setOutboundProperty("SOAPAction", message.getInboundProperty("SOAPAction"));message.setOutboundProperty("Content-Type", requestContentType);def currentRouter = routers.find {r -> r.serviceId == requestSvcId;}logger.info "======== service address: ${currentRouter.address}"if (currentRouter != null) {if (requestContentType != '') {currentRouter.contentType = requestContentType}message.setSessionProperty("router-info", currentRouter)}message

Mule Flow:

<?xml version="1.0" encoding="UTF-8"?><mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" 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" version="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd 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 ">    <flow name="mule-esb-route-sampleFlow1" doc:name="mule-esb-route-sampleFlow1">        <http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:9999/esb" doc:name="HTTP" />                <logger message="---------- #[groovy:message.toString()]" level="INFO" doc:name="log request"/>                <scripting:component doc:name="Groovy">            <scripting:script engine="Groovy" file="router.groovy"/>        </scripting:component>        <http:outbound-endpoint exchange-pattern="request-response"               address="http://#[groovy:message.getSessionProperty('router-info').address]"              doc:name="HTTP"/>             </flow></mule>

接入方通过向 http://localhost:9999/esb/{serviceId} 来发送请求使用服务。groovy 中定义的 List routers 即可看成是ESB平台内部管理的路由表
(实际使用时会保存在数据库中或者缓存容器中便于即时修改维护),Mule 通过 relative path 获取的 {serviceId} 来做映射。
最后将变量交给 Mule 的 <http.outbound-endpoint> 将请求转发到真实服务上去。

顺便做个广告,下面是我在 InfoQ 做的分享的PPT和视频,有兴趣的童鞋请移步观看。

http://www.infoq.com/cn/presentations/electricity-supplier-in-the-enterprise-service-bus


原创粉丝点击