ESB與SOA的關系
談及企業服務總線(ESB),在有面向服務的架構(SOA)實施經驗的開發者眼中一定不會陌生。這些年,人們一直在談論它,以至有些人認為“實施SOA一定需要ESB”,或“只要將ESB架起來了,我們就SOA了”。這些說法有可取之處,也存在片面之嫌,由於業界對於ESB沒有統一、標准的定義,所以一千個人眼中有一千個“ESB”也就成了情理中的事情了。然而,怎么才能將ESB用好?我們需要清楚地認識ESB在SOA中所扮演的角色,理解哪些工作是ESB的職責之內,哪些卻不是。只有正確地認識了ESB的職能,並委以恰當的任務,才能將它用在刀刃上、發揮其巨大的能量。
本文是這樣安排的:
第一部分,簡單介紹ESB在SOA中所起的作用。
第二部分:介紹三種常見的ESB的誤用。
第三部分,介紹三種推薦實施。
第四部分,對ESB產品發展方向的展望。
申明:文中的出現所有觀點僅代表作者個人看法,不代表作者所供職公司的觀點。
正確理解ESB在SOA中的作用
平心而論,ESB的確是SOA中一個非常重要的集成層組件(Integration Layer),不論是OpenGroup發布的SOA參考架構,還是幾大主流SOA供應商(參考IBM通過參考架構實施SOA解決方案 ,Oracle與F5的SOA參考架構,Microsoft的BizTalk ESB Toolkit中對ESB的定義),都將ESB置於SOA架構的核心位置。
事實上,ESB在SOA中扮演着重要的角色,在技術層解決了SOA的整合問題,耦合了應用與應用之間的集成邏輯,使得SOA更靈活,更易於擴展,更敏捷。有了ESB,新建的服務消費者應用程序不需要關心服務的提供者在哪里,使用何種通訊協議,與其交互的數據是怎樣的……,它只需向ESB發出請求,使用開放的、標准的通訊協議。相反,若某個可重用的價值較大的服務位於某一個遺留系統中,而由於種種原因,該遺留系統不能在短期內重寫,此時ESB可以架起該服務與其使用者之間溝通的橋梁。當然,ESB的作用遠不止這些,業內也有很多討論,本文不再贅述。讀者可在Google上搜索ESB Patterns獲得相關資料。
然而,ESB並非“救世主”,它注定也不可能解決應用系統整合中出現的所有問題。道理很簡單,計算機發展歷史長從沒有出現過一個產品/工具可以滿足所有的應用需求,技術發展得很快,需求發展更快,所以技術永遠跟不上需求。此外,ESB或ESB產品有其特定的適用范圍,它是基礎設施層的概念/產品,解決的是整合中的常見問題,比如服務連通、路由、消息豐富、服務的注冊/查找/發布等服務的管理、服務監控和質量保證等。ESB不能解決的問題比其能解決的問題多很多。比如,讓它去做人工流程的編排是不合適的,讓它提供門戶類產品那樣的用戶交互也是極其困難的……。
筆者支持過許多客戶項目。在這些項目中,有的客戶將ESB用的好,有的則勉強用上,用的功能很簡單,有的則用ESB做一些原本不屬於它該做的工作。在這里,筆者僅從個人的立場,分享自己這些年來積累的ESB實施經驗。下面列出筆者常看到但不推薦的實施和筆者在實施ESB的過程中積累的一些較好的實踐方式,供讀者參考。同時歡迎批評指正。
不推薦實施
挾ESB以令外圍應用
- 現象:
ESB的架構師在ESB上設計一套標准的數據接口(通用的XML格式),規定使用統一的協議(如Web Service/HTTP)。所有的ESB服務消費者和接入ESB的服務必須符合該標准。其目的是為了簡化ESB上的開發工作。這就是一種“挾天子以令諸侯”的做法,因為在實際情況中,可能領導規定了“所有的服務必須要經過ESB,即便是透傳”。
- 分析:
國內的ESB實施者大多數是一些SI/ISV,出於成本/人力或其他個方面的原因,總會有一些架構師希望達成這樣一個目標:我能否設計/實現一個一勞永逸的ESB中間平台,將來不論哪種服務都可以方便地接入到ESB上?
這是一個很浪漫很理想的目標,但這個目標是不可能實現的。原因有二:其一,仲裁邏輯一般是非常具體的,具體的服務有具體的整合需求。譬如,一個服務提供者基於HTTP提供了一個Web服務WS1,而我們希望將這個服務通過ESB暴露給兩個客戶端ClientA,Client B;Client A使用XML/HTTP訪問服務,而Client B卻使用SOAP/JMS訪問該服務,如圖1所示。有過ESB實施經驗的人都能看出里面的仲裁邏輯是非常具體的,我們要考慮的不僅僅是協議之間的差別,還需要考慮消息格式的差別。其二,如果有這樣的設計/實現存在,ESB產商為何不把這個特性直接實現了呢?你也許會說產商不理解具體的業務,而具體的業務是復雜的,SI/ISV卻了解這些復雜業務。而事實上,ESB解決的更多是技術層面的工作,業務層面的工作大多數不屬於ESB的范疇,復雜的業務邏輯不是在業務系統中實現,就是在其它SOA組件中實現,如流程管理引擎。

圖1. ESB的主要功能之一是連接異構協議和數據。
- 原因及危害:
該實踐出現的根本原因是:沒有認清ESB本身的作用,過分看重了ESB之上的設計能力。其實,ESB針對的是一個個功能各異的整合邏輯,服務之間的整合邏輯也是迥異的。所以,一勞永逸的ESB之上的架構是不存在的。
其危害是:丟失了ESB本身最強大的連通性方面的功能,正式因為需要聯通的應用之間的差異性,才逐漸發展出了ESB這樣的組件。如果要求所有的外圍應用的協議標准和數據標准都統一了(事實上,這是不可能實現的,特別在與第三方應用整合時),那么ESB的必要性就遜色不少。
- 建議:
不要試圖實現一個一勞永逸的ESB之上的架構,這個架構不存在也沒有其存在的必要性。不過,筆者並非反對設計。實際上,ESB上可以設計,也可以通過一定的設計實現某種程度的自動化,靈活性和通用性。舉個例子,某一組功能類似的服務,對這一組服務的所有請求必須進行審計、安全加固等操作,對於這一類需求,我們可以事先在ESB上設計好相應的技術組件/服務,然后在ESB的仲裁流中間調用該組件/服務即可。
用ESB實現業務流程
- 現象:
有些架構師看到ESB支持服務組合(Service Composition)模式,進而認為可用該模式來實現業務流程。因此,ESB產品就演變成了BPM產品。
- 分析:
如果讀者關心過ESB的通用使用模式,就會發現ESB的服務組合模式(Service Composition)與BPM中的服務編排(Service Cherography)非常相似,二者都是將細粒度的服務組合/組裝起來,形成大粒度的服務,或者業務流程。
事實上,二者有着本質的區別。其一:ESB是一個偏向技術層整合的組件,比如將“客戶資料查詢”服務與“日志”服務組裝起來,得到的結果還是“客戶資料查詢”服務,只是在仲裁流中間插入了一個新的附加功能,即“日志”服務。BPM中的服務編排的含義很側重於業務流轉的概念。比如“項目立項審批流程”,該流程的實現可能需要來自幾個相關系統中的服務的參與,它們可能是“立項申請”,接着是“一級職能經歷審批”,然后是“部門經理審批”,“財務審批”等。這些服務流轉起來形成的是一個完整的業務流程。其二:ESB上的服務組合是無狀態的,ESB運行時會為每個請求建立一個實例來執行其仲裁邏輯,請求與請求之間沒有時序關系,是互不相干的、各自獨立的。相反,BPM上的服務編排這不一樣,未完成的業務流程實例一直會存活在BPM運行時中,存活期可能為一天、一周、甚至1個月或更長;請求與請求之間可能存在着一定的關聯性,比如對與一個項目(相同的項目ID)的立項審批流程,一級職能經理、部門經理和財務對流程發出的請求都是針對同一運行時實例的。
- 原因及危害:
除了其他非技術的因素外,導致該實踐的一個重要原因是:混淆了ESB的服務組合與BPM的服務編排兩個概念。
危害:讓ESB實現BPM,特別是長運行的流程時,雖然在技術上可以實現,但是這違背了ESB產品的設計理念,會大大影響其ESB運行時的整體運行效率。
- 建議:
認清技術上的服務組合與服務編排之間的差異,分析每個產品所屬的概念范疇,選擇合適的產品解決合適的問題。
用ESB實現大數據傳輸
- 現象:
將ESB用於在兩個系統間傳輸大量數據,比如傳輸視頻文件、大文檔等。在這些場景中傳輸的信息/文件/消息有一個共同的特點:只使用了ESB提供的連通性功能,而沒有使用其他功能,如消息解析,轉換,路由等。
- 分析:
為了在ESB市場上搶占有利位置,各大廠商提供的ESB產品的能力越來越強。ESB產品的設計是支持消息從一個系統傳到另一個或幾個系統的。所以,一些架構師利用ESB產品本身提供的此項功能架設了一個數據傳輸總線。
可是ESB並不適合完成該項功能,雖然它可以實現這一功能,但這並非最佳實踐。ESB作為企業級的服務聯通、管理平台,需要穿透ESB的服務應該是企業內重用可能最大、價值最大的那些服務,應用程序對這類服務的訪問應該非常頻繁,因此同一時刻需要ESB支撐的業務可能非常繁重。所以,ESB產品的設計初衷是實現一個無狀態、高吞吐的服務總線,為企業內重要的業務服務提供透明、標准、開放的接入能力。
- 原因及危害:
這種實踐的原因是過分放大了ESB對數據的傳輸能力,如果在ESB傳輸巨大的信息,可能會導致ESB整體性能的下降,損害其他重要服務的QoS。
- 建議:
如果需要傳輸的數據有解析或轉換的需求、或者需要根據數據里的信息進行某種路由或其他仲裁邏輯需求時,則建議使用ESB;但如果同時消息體又過與龐大,可以考慮將需要解析的消息與不需解析的數據部分進行拆分,通過其他專門的數據傳輸平台去傳輸不需解析的部分,如FTP,數據庫備份機制等,而在ESB中實現該傳輸任務的控制流。
推薦實施
服務要管理起來
ESB的一個重要功能是將企業內/合作伙伴處的服務以開放的、標准的服務方式暴露出來,使得服務消費者能夠便利地查找到服務,以促進服務的重用、管理。而許多ESB產品不包含服務的注冊、存儲、發布、訂閱等功能,這些功能包含UDDI庫中。所以,ESB一般需要一個服務注冊/存儲庫與之協作。ESB執行各種仲裁邏輯,而注冊庫為ESB提供必要的元數據信息。
服務注冊庫可以存儲服務的元數據,包括服務的描述、功能、版本、輸入/輸出消息的模式、服務端點、SLA、安全策略等內容,這些信息可被ESB用來進行消息格式驗證、服務的動態路由、執行安全策略和SLA保證等。
ESB可以多級實施,可以實現整個企業級/全國級的ESB,也可以實現部門級/地市級的ESB。服務消費者應該能在注冊庫中找到自己所需要的服務,獲得調用該服務所需的位置、服務的描述文件、請求/相應消息格式等信息。若是沒有注冊庫,則隨着ESB接入的服務越來越多,仲裁邏輯不斷增加,必將造成服務管理的混亂。最后抵消了ESB帶來的價值。
復雜的動態路由規則應服務化
路由是ESB中非常重要的仲裁邏輯之一。路由場景是非常普遍的。譬如,針對不同的客戶提供不同QoS的場景,執行時需根據客戶的類型將其路由到不同執行能力的服務提供者;再比如當響應消息到達ESB時,總是需要將該響應消息送回最初的服務請求者處。
路由可分為靜態路由和動態路由。靜態路由指得是設計時已經明確路由分支的情況,而動態路由的路由分支選擇是在運行時動態確定的。不論是靜態路由還是動態路由,路由分支的選擇一定伴隨着一個或一系列決策依據。決策依據可簡單如一個If-Else語句,也可以復雜到需要通過多維決策表並通過多次判斷才能得到最后的路由分支。
對於復雜的路由,推薦將路由規則的邏輯外部化,並將它服務化,如圖2所示。如此,仲裁邏輯在分發消息前可先訪問該路由規則服務,從而得到明確的路由結果。至此,可能有人會問到,“復雜”與“簡單”如何界定。這個問題沒有統一的規定,根據筆者以往的實施經驗,如果符合以下條件之一,就可以認為是復雜的路由規則:
- 判斷維度大於等於2
- 連續決策節點大於等於3
- 路由分支可能隨時增加或減少

圖2. 動態路由規則服務化。
將復雜的動態路由規則服務化的好處簡單明了。首先,讓復雜的規則服務化,可以降低仲裁邏輯的變化性。當規則發生改變時,不需要修改仲裁邏輯,而只需更改規則服務即可。進一步,如果該規則服務是由某種專業的規則引擎實現的,更改起來將更加簡單。其二,由於ESB產品的實現與設計並無業界的標准,所以基於ESB產品的配置開發無法在不同產品間互相移植。將規則服務化之后,還可減少仲裁邏輯在不同的ESB產品間移植時所需的工作量。最后,規則的服務化符合SOA原則,企業內業務規則應該以服務的形式管理起來,以促進規則的重用。
轉換邏輯的實現盡量選用XSLT
數據轉換也是仲裁邏輯中非常常見並且重要的功能。同一數據在不同的業務系統中表現方式可能不一樣,如上文例子中的Client A訪問服務WS1的情況,仲裁邏輯需要將XML消息轉換為調用服務A的SOAP消息。
一般而言,大多數ESB產品都提供了多種數據轉換的方式,很多產商宣傳中力推的都是“拖拽式”可視化映射的轉換方式。該功能聽起來的確很酷,看上去很直觀。但是正如我們前面所說的,ESB是一個偏向技術層整合的組件,業務人員一般不會關心XML是如何轉換成SOAP的。所以,對於開發者來說,這種“炫”功能並無太大吸引力。更重要的是,他們可能非常習慣於自己的編程語言,如Java、XSLT、ESQL和PHP等,這些語言操作起來要簡單很多。筆者本人就不太喜歡使用可視化隱射的方式去實現數據轉換的需求,尤其碰到需要循環運行、復雜計算等轉換邏輯時,在可視化映射上實現起來更加不容易。
在此,筆者推薦的方式是使用XSLT實現數據轉換的功能,如圖3所示。原因如下:首先,XSLT是一個標准的XML轉換語言,使用XSLT實現的轉換邏輯可很輕易地在不同ESB產品間移植。據筆者調查,幾乎所有主流商業ESB產品都支持XSLT的轉換機制。其二,選擇XSLT還可增加ESB之上的架構靈活性。因為仲裁邏輯中的轉換邏輯是最計算密集型的邏輯,它最消耗CPU,影響整體性能。在這種架構中,我們很容易地將此轉換邏輯剝離出仲裁邏輯,由一些專門的XML轉換加速軟件/硬件(如IBM WebSphere DataPower)來完成這一工作。這樣的設計可提高架構的靈活性,通過分布式計算的方式提高整體計算性能。

圖3. XSLT實現數據轉換邏輯及架構擴展
展望
在SOA架構中,ESB扮演的重要角色是毋庸置疑的。隨着企業架構的不斷演變和進化,ESB也不能一層不變。它只有與時俱進,才能順應技術和思想的發展和進步。隨着RESTful Web服務的興起,SOAP服務不再是最受寵愛的標准;SOA架構也在不斷突破企業防火牆,延伸到雲計算的世界里。在這樣的歷史大環境下,ESB至少要需要以下向兩個方向發展,才能在競爭中立於不敗之地,否則就可能被新產品所替代。
首先,ESB需加強對RESTful Web服務的整合支持。RESTFul Web服務相比於SOAP服務有着簡單、易學、易擴展等方面的優勢。將RESTFul Web服務作為SOA的基礎構建元素的呼聲非常高。雖然不通過HTTP傳輸的服務無法轉變成RESTFul服務,但是這種對RESTFul服務的呼聲至少代表了人們向往簡單的願望。筆者認為這種趨勢不可逆轉,ESB產品必須加強對RESTFul服務的整合支持。譬如,可通過ESB將后台遺留的MQ應用的功能轉變成一個RESTFul的服務,供RESTFul客戶端訪問。
其次,ESB需加強與SaaS雲應用的整合支持。隨着雲計算的鋪天蓋地席卷而來,人們對雲的認識越來越清晰,對雲計算經濟越來越認可,雲端應用變得炙手可熱。在SaaS應用越來越受到熱門的歡迎同時,出於安全、性能、已投資資產等方面的原因,企業不可能將所有的數據/應用部署在雲端,所以本地應用與雲端SaaS應用之間的整合必將成為未來幾年最熱的集成需求,這就催生了筆者對ESB第二個方面的展望。
給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至editors@cn.infoq.com。也歡迎大家加入到InfoQ中文站用戶討論組中與我們的編輯和其他讀者朋友交流。
