ESB相關知識點 (1)

1、概述

從本篇文章開始,我們將花一到兩篇的篇幅介紹ESB(企業服務總線)技術的基本概念,爲讀者們理清多個和ESB技術有關名詞。我們還將在其中爲讀者闡述什麼情況下應該使用ESB技術。接下來,爲了加深讀者對ESB技術的直觀理解,我們將利用Apache Camel一起搭建一個ESB技術的服務實現,雖然這個示例不能把目前主流的ESB服務實現中所有功能模塊都保羅進來,但至少可以讓讀者看到ESB技術核心服務完整的工作方式。

2、爲什麼需要ESB

2-1、ESB與SOA

2-1-1、SOA

SOA(Service-Oriented Architecture)中文全稱“面向服務的架構”。放在當下的技術環境(2015/2016年),SOA並不是一個新的概念。但是在SOA剛流行起來的2000年初(SOA的概念最初由Gartner Group在1996年提出),這個架構模型算就是非常流行了。本小節筆者試圖使用最平實的語言向各位讀者介紹SOA概念中的幾個核心內容。

首先SOA是一種架構模式思想,主要圍繞多個“服務”如何進行集成以達到某種目的進行討論。那麼SOA中所定義服務是什麼意思呢?在業務系統中被髮布出來供用戶使用,能夠完成一個完整業務過程的功能,就是服務。

這裏寫圖片描述

  • 服務着眼於完整的業務

    從以上對“服務”的定義可以看出,服務的定義對象是業務系統中的完整業務功能。例如電商系統中“確認訂單”這個功能就是一個服務、計費系統中“當月費用結算”功能就是一個服務;但是CRM系統中,需要完成“工單生成”功能所進行的“用戶登錄”動作就不是服務的定義,因爲使用者進行“用戶登錄”是爲了完成“工單生成”功能的權限驗證步驟,並不是爲了“登錄”而登錄。

  • 服務的粒度雖然相對粗放,但卻可控,目標是重用

    接着討論,“用戶登錄”這個功能在某些情況下也可以滿足“服務”的定義:當用戶中心繫統爲其他所有業務系統統一提供的“登錄”服務被公佈出來時。服務粒度的拆分完全依據業務系統中業務過程進行定義和分析,所以服務的粒度都相對粗放。就像上一段文字中所舉例的“費用結算”服務那樣:可能完成“費用結算”功能,在計費系統內部需要完成 用戶身份確認->上月費用查詢->套餐清單查詢->費用明細生成 這幾個過程。但是這些每一個過程都不會有任何其它業務系統進行單獨使用,也就是說是否單獨公佈這些處理過程對於其他業務系統來說沒有任何意義。

    如果在後續的業務變更/業務重編時,業務設計人員發現某一個業務系統需要單獨使用計費系統的“上月費用查詢”功能,這時就需要計費系統將這個功能作爲一個獨立的服務向第三方業務系統公佈出來。這時,這個功能就滿足了“服務”的定義。

  • 集成的目的是形成一個新的服務

    對企業內部(或者企業間)的業務服務進行集成,被集成的業務服務稱之爲原子服務,集成的目的是重用這些原子服務形成一個新的服務。這樣保證了技術團隊/業務團隊能以最小的代價,最高的效率使用既有服務,但同時也對實現SOA架構思想的軟件提出了更高的要求。

  • SOA需保證屏蔽細節

    使用SOA架構思想構建多個業務系統的集成關係,需要保證每個業務系統屏蔽細節。這些細節包括技術細節和業務細節。從技術細節層面看,無論業務系統使用哪種開發語言、哪種對外傳輸協議、哪種消息格式都可以使用SOA進行集成,並且能夠在SOA架構的實現軟件上完成不同傳輸協議的轉換和不同消息格式的轉換;從業務細節層面看,SOA需要屏蔽業務系統的功能步驟細節。也就是說第三方系統只需要知道調用某一個服務就可以達到業務目的,至於提供服務的業務系統如何實現業務過程則無需關心。

  • SOA讓各業務系統保持鬆散

    SOA架構模型爲多個業務系統進行鬆散集成提供了一個良好的思路:通過屏蔽各業務系統技術細節和業務細節,兼容各業務系統的不同傳輸協議和不同消息格式,可以讓通過SOA進行業務集成的各個業務系統保持低耦合狀態。這是因爲所有協議和消息格式都處於開放狀態,業務集成時各業務系統不需要單獨進行額外的轉換工作,甚至不需要爲基於SOA的業務集成進行任何額外工作,也無須知道對方系統的存在。

如果您所在企業或者客戶的業務系統還沒有達到一個較高的複雜等級,則不建議立即使用SOA架構模型進行業務集成。因爲目前SOA架構模型的各種實現本身就具有一定的複雜性。

2-1-2、ESB

ESB(Enterprise Service Bus)全名:企業服務總線,是SOA架構思想的一種實現思路。既然是一種思路,就有這一實現思路的具體考慮,以及需要解決問題的實際環境:

企業的信息化建設一般經歷很長時間的發展,少則5、6年多則10幾年。所以我們看到某大型企業的信息系統最可能的情況是:存在着多個業務系統,甚至各業務系統負責的功能職責還存在重疊。這些系統採用不同時代的編程語言、編程框架、通訊協議、消息格式和存儲方案。

例如,計費系統可能採用C++ 進行編寫,對外調用功能採用CORBA;年久的CRM系統採用Delphi進行編寫,同樣使用CORBA發佈調用功能,並且最近兩年該企業剛對CRM系統使用C#語言進行了一次升級,但是由於數據存儲層的設計原因,並沒有將老系統的所有數據割接到新系統,所以目前兩套CRM系統都在使用;最新開發的財務聯動系統,採用Java語言開發,並且不再採用應用程序窗口,改爲使用瀏覽器進行頁面展示和用戶操作。這個財務聯動系統多數對外的服務採用HTTP協議對外公佈,還有一部分服務採用Thrift RPC對外公佈……

由此可見,由於各種可見的和不可見的原因,企業信息化系統的建設歷史和現實存在往往紛繁複雜。如果這些系統需要進行服務集成,但是又沒有一個成熟穩定、兼容易用的中間層進行協調,那麼要達到以上的調用要求基本上不可能的(即使實現也相當難以維護和擴展)。

這裏寫圖片描述

那麼爲了滿足SOA架構思想的設計要點,達到既定的工作目標,ESB總線技術至少需要幫助這些業務系統完成以下工作:

  • 多調用協議支撐和轉換

無論業務系統向外部公佈的服務使用哪種調用協議,都可以通過ESB技術進行兼容性轉換。例如A業務系統的服務只接受Web Service SOAP形式的調用,B業務系統的服務卻可以使用Thrift RPC進行調用(不必爲了調用A業務系統而專門去適應A業務系統的協議)。在基於ESB服務的中間層幫助實現兩種協議的轉換。

  • 多消息格式支撐和轉換

無論調用協議攜帶哪一種消息描述格式,通過ESB中間層也可以實現相互轉換。ESB中間層應該支持將JSON格式的信息描述轉換成目標業務系統能夠識別的XML格式,或者將XML描述格式轉換成純文本格式,又或者實現兩種不同結構的XML格式的互相轉換,等等……

  • 服務監控管理(註冊、安全、版本、優先級)

既然ESB要對原子服務進行集成,考慮的問題就比較多了。首先,業務系統提供的服務可能會以一定週期發生變化,例如週期性的升級;失控的業務系統甚至可能呈現完全無預兆無規律的服務變化,例如突發性數據割接導致服務接口變動。那麼ESB的實現軟件中應該有一套功能,能夠保證在這樣的情況下集成服務依然能夠工作。其次,並不是業務系統所提供的所有服務都可以在ESB中進行集成,也並不是所有的服務都能被任何路由規則所編排。ESB應該有一套完整的功能來保證服務集成的安全性和權限。

作爲被集成的業務系統,ESB中如何集成它提供的原子服務,前者是不需要關心的,

  • 服務集成和編排

爲了將多個服務通過ESB技術進行集成形成一個新的服務,ESB技術必須能夠進行服務編排。服務編排的作用就是明確原子服務執行的先後順序、判斷原子服務執行的條件、確保集成後的新服務能夠按照業務設計者的要求正常工作。下圖示例了新服務“工單派發”通過多個業務系統提供的原子服務,按照設置的執行條件在ESB總線上進行工作的過程:

這裏寫圖片描述

實際上ESB技術和本專題之前講過的服務治理技術在架構層面屬同一層:都是對SOA思想的實現思路。但是兩者的應用場景和側重點完全不一樣。

2-2、ESB是EAI的進化

ESB企業服務總線技術是在SOA架構之後出現的,在這之前爲了集成多個系統而使用最多的技術思路是EAI(Enterprise Application Integration):企業應用集成。EAI技術並沒有一個統一的標準,而是對不同企業集成業務系統手段的統一稱呼。

2-2-1、EAI的特徵

這裏寫圖片描述

從上圖可以看出,EAI主要的作用還是完成各中消息格式的轉換。由於EAI主要的使用場景是在上世紀八九十年代,所以如果從現在往回看EAI所支持的傳輸協議也是很有限的(不過肯定還是基於7層/5層網絡協議的)。不過,在SOA架構思想出現之前,EAI技術確實爲企業實現業務系統集成提供了一個可行的思路。

需要注意的是,EAI技術並不是SOA架構思想的一種實現。它出現在SOA架構思想之前,最重要的是它缺少SOA的基本要素——着眼業務服務,粒度粗放但卻可控:由於EAI中並沒有流程編排的功能,所以這些原子服務並不能有機的結合在一起,形成新的服務,也無法在EAI中重新梳理業務過程,以便要求原子服務進行相應的粒度拆分。

2-2-2、哪些特徵得到了進化

這裏寫圖片描述

  • 在消息轉換上的進化:

上一小節已經提到,由於EAI技術出現的時間比較早,在那個時候基本上還沒有太多行業標準的傳輸協議和消息格式,使用最多的就是XML格式,還有半結構化的文本數據。所以,在公司內部實現EAI技術時,一般不會考慮太多的行業標準,使用公司內部自定製的傳輸協議和消息格式就能夠搞定。雖然這樣做也有一定的好處,就是公司內部的業務團隊都清楚這些自定製的格式代表的業務意義,降低了一定的溝通成本。但這樣做的問題也顯而易見,如果日後需要和兄弟公司的業務系統進行集成,那麼之前被節約的工作時間又會被浪費。

成熟的ESB產品中就不會這樣考慮問題,一般採用開放性的傳輸協議和消息格式。例如使用HTTP傳輸協議攜帶查詢請求、使用FTP傳輸協議攜帶上傳的文件信息;採用XMPP消息格式描述IM即時通訊內容,採用MQTT消息格式描述物聯網設備採集內容、使用AMQP消息格式描述MQ的內容。

  • 在流程編排上的進化

EAI沒有流程編排的硬性要求,也就是說他只面向數據轉換過程,並不面向業務服務。所以各位讀者可以這樣看待這個問題:SOA架構思想出現後,偉大的技術屌絲團隊立馬發現了面向服務的概念對EAI軟件的建設性作用,廢寢忘食的爲各種業已運行的EAI軟件加入了各種面向服務的要素,最關鍵的就是加入了服務編排等面向服務的管理功能。實際上,以上情況就是現實中最真實的情況。

  • 在服務管理上的進化

從EAI到ESB實際上是業務管理方法上的優化,但就像上文中提到的那樣,並不是所有企業都適合使用基於SOA架構思想的ESB技術。目前大部分企業的對內部業務系統的集成手段還是更貼切於EAI技術的定義,這是因爲這些企業的業務系統還沒有達到較高的複雜度(出現最多的情況就是他們只有一套必須的財務系統)。

所以,EAI並不是淘汰品,ESB也不是什麼“跨時代”的偉大發明。後者就是前者不斷完善的產物,把兩者之間的關係說成“基礎版”和“升級版”更爲貼切。一些網絡文章一味貶低EAI提升ESB的地位,這是不正確的,有的企業或者平臺,還沒有複雜到必須使用ESB,那就可以不使用ESB技術。所以只有適合自己架構纔是理想的架構。如果是某個ESB廠商的軟文,目的是什麼就仁者見仁智者見智了。

2-3、ESB與循環依賴

ESB技術保證了各個業務服務的低耦合性,間接避免了各業務系統在集成時技術團隊有意無意製造的服務循環依賴問題。

2-3-1、什麼是循環依賴

首先我們要講清楚什麼是循環依賴,以及循環依賴的在程序設計層面、軟件產品設計層面、頂層架構設計層面上可能出現的場景。從概念模型上講,只要兩個或多個元素產生相互依賴關係,就可以看成產生了循環依賴:

這裏寫圖片描述

上圖是兩個依賴關係正確的示例:A元素正常工作依賴於B元素的正常工作,或者A元素的正常工作依賴於B、C、D元素的正常工作。這裏的A、B、C、D四個元素可以指代四段代碼,也可以指代一個業務系統中四個功能模塊,還可以指代頂層架構設計中的4個獨立工作的業務系統。

這裏寫圖片描述

循環依賴在邏輯層面上是一個有向循環圖。上圖中展示了兩個錯誤的依賴關係實例:A元素正常工作依賴於B元素正常工作的同時,B元素正常工作又依賴於A元素的正常工作。那麼究竟哪個元素能夠首先正常工作起來呢(先有雞還是先有蛋)?右側圖展示了三個元素的循環依賴,A元素依賴於C元素,C元素依賴於D元素,D元素又依賴於A元素。那麼A、C、D三個元素究竟哪一個元素纔是底層的基礎元素呢?

  • 代碼層面的循環依賴:

代碼層面的循環依賴是開發人員最容易出現的編碼錯誤,不過有的時候也不能全怪開發人員,畢竟業務設計者從需求理解階段可能就出現了問題。以下示例了代碼層面的循環依賴:

/**
 * 此類依賴於BusinessB
 * @author yinwenjie
 */
public class BusinessA {
    private BusinessB bb;
    public BusinessA(BusinessB bb) {
        this.bb = bb;
    }

    ......
}

/**
 * 此類依賴於BusinessC
 * @author yinwenjie
 */
public class BusinessB {
    private BusinessC bc;
    public BusinessB(BusinessC bc) {
        this.bc = bc;
    }

    ......
}

/**
 * 此類依賴於BusinessA
 * @author yinwenjie
 */
public class BusinessC {
    private BusinessA ac;
    public BusinessC(BusinessA ac) {
        this.ac = ac;
    }

    ......  

    // 接下來我們試圖實例化BusinessA...
    public static void main(String[] args) {
        // 怎麼實例化BusinessA呢?
        // new BusinessA(new BusinessB(new BusinessC(new BusinessA(!程序員已經發瘋!))))
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

實際上按照這樣的引用結構和構造函數要求,實例化BusinessA這件事情是永遠無法完成的

  • 功能層面的循環依賴:

業務系統的功能間也可能出現循環依賴。相對於代碼層面的循環依賴,功能模塊層面的循環依賴更能夠影響一款業務系統的設計質量。筆者曾參與的一款軟件,客戶方曾經提出過這樣的一個業務需求:

貨運系統中在創建新的“發車單”時,必須選擇空閒的司機和空閒的貨車(當然貨車類型是要判斷的)。空閒的司機和空閒貨車缺少任何一樣都不能完成“發車單”的創建。但同時爲了記錄某輛貨車上一次對應的“發車單”,客戶要求只能在創建新的發車單後,貨車才能解除之前的“發車單”綁定關係,變成“空閒貨車”。

這裏寫圖片描述

那麼問題來了,如果只有完成新的“發車單”創建後,貨車才能解除和之前“發車單”的綁定關係,那麼新創建“發車單”時,“空閒的貨車”從哪裏來呢?實際上客戶方不懂技術,是我們在需求調研階段遇到的算一個問題的問題,但關鍵看需求人員從哪個方面着手向用戶解釋引導用戶對需求邏輯進行分析。不一定用技術語言直接告訴用戶,他的需求在技術層面上不符合邏輯。

  • 架構層面的循環依賴:

多個業務系統在進行集成時,他們也可能會出現循環依賴。特別是參與集成的業務系統越多,這種循環依賴的情況就越容易出現:

這裏寫圖片描述

在系統數量還沒有達到一定數量時(通常來說這個閥值爲4),系統間的循環依賴最可能是由業務人員/技術人員無意造成。這時,系統間的依賴關係還處於一個可控級別,即使出現系統間循環依賴的情況,技術團隊/業務團隊也可以快速進行糾正。但是,當參與集成的業務系統數量超過可控制的閥值數量後,這個檢查和糾正工作就不再是人工可及的範圍了。如下圖所示的5個系統進行集成時,很容易出現系統間循環依賴的情況:

這裏寫圖片描述

2-3-3、避免循環依賴

  • 依賴倒置原則預防循環依賴

依賴倒置原則可以幫助預防代碼層面和功能模塊層面的循環依賴。頂層架構層面的循環依賴問題,也可以遵循這個原則進行設計來避免。依賴倒置原則在很多書本、網絡資料上都有很詳細的介紹。基本上這個原則是在說兩個點:高層次模塊不應該依賴於低層次模塊,模塊的實現都應該依賴於抽象(接口),而抽象(接口)能夠屏蔽功能設計上的細節。

這裏寫圖片描述

  • 對循環依賴的自動檢測

如果您負責的產品是遺留產品。在經過多個設計人員更替後,產品內部設計或多或少出現了一些循環依賴問題,這時該怎麼辦?您要做的首先是檢查產品的哪些模塊出現了循環依賴,再思考修改方法。目前市面上有很多這樣的工具,可以幫助您檢查代碼層面和系統模塊層面的依賴關係是否良好,這裏筆者推薦SonarQube。以下截圖是筆者經歷過的一個項目中,某個子模塊通過SonarQube進行檢測的結果:

這裏寫圖片描述

呵呵,V0.0.9版本,看來還有若干個類的複雜度偏高,說明模塊中使用的設計模式還有改進空間。好吧,這個子系統只是開了一個頭,目前已經發展到V0.5.3的版本號,代碼行數也快接近5萬行了。不過作爲這個子模塊的作者之一,本人自認爲包耦合度一直控制得很好,直到現在也沒有出現包循環依賴的情況。

  • 抽離底層能引導業務人員優化依賴結構

在上一小節“功能層面的循環依賴”中我們舉了一個司機-貨車-發車單三個元素在業務功能層面的循環依賴問題。現在我們接着這個問題繼續討論。客戶之所以要在新的“發車單”創建後,才解除貨車和歷史“發車單”的綁定關係,是因爲用戶擔心軟件失去對歷史“發車單”的跟蹤能力,最後無法統計車輛使用率或者司機績效情況。但實際上,客戶完全無需擔心出現這樣的情況,瞭解客戶的真實想法後,需求人員就能引導客戶開闢一個新的日誌模塊,這個日誌模塊處於整個業務系統設計的更底層,專門跟蹤各種歷史行爲,車輛的、人員的、財務的、貨品的,都行:

這裏寫圖片描述

我們可以用這種剝離循環依賴元素中底層能力的方式,解決循環依賴問題。這種解決思路不但適用於業務系統功能間的解耦,同樣適用於代碼級別或者系統頂層架構級別的解耦。

  • 使用中間層/基礎層對依賴元素進行隔離

ESB爲各個業務系統的集成提供了一個理想的中間層/基礎層。通過從中間層/基礎層抽離的底層能力,我們將所有業務系統的集成工作交由ESB完成:

這裏寫圖片描述

注意:雖然ESB承擔了原本在系統內部完成的業務集成工作。但是根據依賴倒置設計原則,ESB也只是依賴於各業務系統註冊在ESB總線上的調用接口,業務系統中功能的具體實現對於ESB來說是透明的。

========================================== 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章