[SOA] Mule ESB 3.x 入門(三)—— 訊息路由
阿新 • • 發佈:2019-02-16
在前面兩篇博文基礎上,繼續來看看如何利用 Mule 來實現簡單的訊息路由。訊息路由是ESB平臺上最基本最重要的功能,它是指通過一定的規則將訊息從一個端點發送到另一端點。通常ESB平臺上會統一管理很多服務,為了便於使用和管理通常會對外暴露一個唯一入口,通過請求攜帶的路由資訊來進行分發。
如下圖所示:
接入方通過向 http://localhost:9999/esb/{serviceId} 來發送請求使用服務。groovy 中定義的 List routers 即可看成是ESB平臺內部管理的路由表
(實際使用時會儲存在資料庫中或者快取容器中便於即時修改維護),Mule 通過 relative path 獲取的 {serviceId} 來做對映。
最後將變數交給 Mule 的 <http.outbound-endpoint> 將請求轉發到真實服務上去。
順便做個廣告,下面是我在 InfoQ 做的分享的PPT和視訊,有興趣的童鞋請移步觀看。
如下圖所示:
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和視訊,有興趣的童鞋請移步觀看。