在前面一個專題中,我們列出了一個ESB系統所需要關心的所有方面的關鍵組件,這里介紹其中的Message Channels所關注的問題及相關的模式。
Message Channel主題之下包含以下模式,分別用于解決channel中不同方面的問題:
l Point-to-Point Channel
l Publish-Subscribe Channel
l Datatype Channel
l Invalid Message Channel
l Dead Letter Channel
l Guaranteed Delivery
l Channel Adapter
l Messaging Bridge
l Message Bus
當兩個應用需要交換數據,它們通過連接兩端的channel來發送數據。發送的應用可能不知道哪個應用將接受數據。然而,通過選擇特定的channel來發送,發送者知道接受者將是守候在channel另一端等待數據的應用之一。通過這種方式,生產數據的應用有了一個同數據消費者通訊的途徑。
Message Channels面對的各個主要問題:
如果一個應用要傳輸或接受數據,它一定會用到一個channel。問題是你的應用要知道要使用什么樣的channel,以及用它來做什么。
固定的channel集合 - Channel中討論的一個主題是,一個應用可用的Message Channel集合一般是固定的。設計一個應用時,一個開發者必須知道將某種類型的數據放到哪里可以同其他應用共享該數據,以及從什么地方可以找到其他應用的特定數據。這些通訊路徑不會在運行期動態的創建和發現;它們需要在設計期間就確定下來,以便應用知道它的數據從哪里來以及數據將去哪里。( 雖然大多數channel必須被靜態定義使正確的,但是也有例外,有些情況下動態channel是很好用的。一個例外就是Request-Reply模式中的reply channel。請求者可以創建或者獲得一個應答者不知道的新的channel,并在請求消息中指定該channel為Return Address,應答者就可以使用它。另外一個例外是支持集成channels的消息系統實現。一個接受者可以訂閱一個集成體系的根channel,然后發送者可以發布消息到一個子channel,而接受者不需要知道子channel,仍然會收到消息。這些都是不常見的情況,channel通常仍然是在部署之前被定義,并且應用被設計連接到一個已知的channel集合 )。
決定channel的集合 - 一個相關的主題是,誰決定那些Message Channel是可用的 - message系統還是應用程序?換句話說,是由消息系統確定一些channel,然后要求應用程序使用它們?還是應用決定它們需要什么channel,然后要求消息系統提供它們?這個問題沒有一個簡單的答案,設計必須的channel集合是迭代的。首先,應用要決定消息系統提供哪些channel。然后應用將圍繞這些channel設計它們的通訊,但是如果這樣是不可行的,它們將需要添加額外的channel。當一些應用已經使用了一個確定的channel集合,當加入新的應用,它們將使用已存在的channel。當為應用添加新的功能,它們需要新的channel。
單向channel - 另外一個經常引起混淆的是一個Message channel是單向的還是雙向的。技術上來說,兩者都不是,一個channel更像是一個桶,一個應用放入數據,另外一個應用從中取出數據。但是由于數據是放在消息中從一個應用傳到另一個,這使得channel具有方向性,使它變成單向的。如果一個channel是雙向的,應用將從中發送和接受數據,雖然技術上是可行的,但是會有小小的問題,應用將有可能持續的取出自己放進去的希望發送給其他應用的消息。所以,為了實踐性的目的,channel是單向的。作為結論,兩個應用如果有雙向通訊,它們需要兩個channel,每個方向一個。
如何使用Message channels:
現在我們來討論以下如何使用channel。
一對一或者一對多 - 當你的應用共享一些數據,你希望只將它共享給一個應用還是對它感興趣的所有應用?要傳送數據到一個單獨的應用,使用Point-to-Point Channel。這并不意味著發送到這個channel的每個數據都發送給同樣的接受者,因為一個channel可能有多個接受者。它意味著,實際上,保證每個數據都被同一個應用接收。如果你想讓所有接收應用都能接收數據,使用Publish-Subscribe Channel。當你通過這種方式發送數據,channel將高效的復制數據到每一個接收者。
什么類型的數據 - 任何內存中的數據都有一個類型。另一方面,所有數據都是一些bytes集合。消息系統工作同這類似,消息內容必須符合某些類型以便接受者了解數據的結構。Datatype Channel認為在一個channel中的數據必須擁有同樣的類型。這也是為什么消息系統需要很多channel的主要原因(每個channel一種格式)。如果數據可以是任意的格式,那么消息系統在兩個應用之間只需要兩條channel。
無效的和過期的消息 - 消息系統可以確定消息被正確的傳輸,但是它不能保證接受者知道如何處理它。接收者對數據格式和意義存在期望。當它接收到一個不符合期望的消息,它什么也不能做。它們能作的,就是將這個陌生的消息放入到一個特別設計的Invalid Message Channel并希望某些監控這個channel的工具能夠取出這個消息,并指出該如何處置它們。許多消息系統有一個類似的內建特征,一個Dead Letter Channel,用來存放成功送出但卻無法成功投遞的消息。另外,一個系統管理工具應該監視Dead Letter Channel并且決定如何處置這些無法投遞的消息。
故障檢測 - 如果一個消息系統發生故障或停機維護,它的消息會怎樣?當它重啟并重新運行,它的消息能否還在它的channel中?默認的:不會;channel將消息存儲在內存中。然而,Guaranteed Delivery將channel持久化以便將它們的消息存儲到硬盤上。這會影響效率,但會使消息更加可靠,即使消息系統是不可靠的。
非消息客戶端 - 如果一個應用不能連接到一個消息系統但是仍然想要參與消息怎么辦?通常它只能自認倒霉了,但是如果消息系統可以通過某種方式連接到應用系統 - 通過它的用戶界面,它的service API,它的數據庫,或者一個TCP/IP或HTTP這樣的網絡連接 - 那么消息系統可以使用一個Channel Adapter。這允許你連接到一個或多個連接到應用的channel而不必改變應用或者可能也不需要一個同應用運行在同一個機器上的消息客戶端。有時‘非消息客戶端’真的是一個消息客戶端,但是只有連接的是其他消息系統的時候。
通訊中樞 - 隨著越來越多的企業應用系統連接到消息系統以便通過消息暴露他們的功能,消息系統變成了企業中一站式功能的集散地。一個應用只需簡單的知道用哪個channel來請求功能,以及從哪個監聽結果。消息系統本質上變成一個消息總線,一個提供所有企業應用甚至變化中的應用和功能的中樞。你可以更快速的集成。
如你所見,使用消息構建應用不僅僅是將他們連接到消息系統并發送消息。消息必須使用Message Channel來發送。Channel必須被設計為某個目的服務,比如基于被共享的數據類型,共享數據的應用類型,和接收數據的應用。