脈絡:企業整合系統天生是分散式的——「讓迥異的系統彼此通訊」正是企業訊息系統的定義性特質之一。多數情況下,這些應用程式散布在多個網路、建築、城市甚至大洲上。
分散式架構的管理難題#
分散、鬆散耦合的架構帶來彈性與可擴展性,同時也為管理與控制帶來嚴峻挑戰:
- 怎麼知道所有元件都還活著? 單純看行程狀態不夠——行程分散在許多機器上。而且若拿不到遠端機器的狀態,那是代表遠端機器故障,還是與它的通訊被干擾了?
- 除了「活著沒」,還得監控系統的動態行為:訊息吞吐量多少?有沒有異常延遲?通道是否被塞滿?其中有些資訊需要追蹤訊息在元件之間或穿過元件的時間,因而需要蒐集並整合來自不只一台機器的資訊。
- 光讀取資訊還不夠——常常需要在系統運行時做調整或改設定,例如把記錄功能開開關關。
為什麼屬性檔行不通#
許多應用程式用屬性檔讀設定、用錯誤記錄檔回報錯誤。只要應用程式只有一台機器(或機器數量很少),這通常管用。
但在大型分散式方案中:
- 屬性檔得用某種檔案傳輸機制複製到遠端機器,這要求每台機器的檔案系統都能被遠端存取——這可能造成安全風險,而且若機器是透過網際網路或廣域網路連接、不支援檔案對應協定,就更困難。
- 各機器上屬性檔的版本還得小心管理——一場等著發生的管理惡夢。
為什麼不直接用訊息傳控制命令#
很自然會想利用訊息基礎設施來做這些事——送一則訊息給元件來改變它的設定,控制訊息就像一般訊息那樣被傳輸與路由。這解決了多數通訊問題,卻也帶來新挑戰:
- 控制訊息應該受到比一般應用訊息更嚴格的安全政策約束——一則格式錯誤的控制訊息,很容易就能把一個元件搞掛。
- 若某個元件故障、訊息在通道上堆積,我們送一則控制訊息去重置它,這則控制訊息也會跟其他訊息一起排隊,根本到不了那個陷入困境的元件。
有些訊息系統支援訊息優先權,能把控制訊息移到佇列前端;但不是所有系統都有這能力,而且當佇列滿到拒收新訊息時,優先權也幫不上忙。
反過來說,有些控制訊息的優先權其實低於應用訊息:若元件定期發布狀態訊息,延遲或遺失一則「我還活著」的控制訊息,麻煩程度遠低於延遲或遺失「一百萬美元的訂單」那則訊息。
解法#
系統中每個元件現在都連上兩套訊息子系統:
- 應用訊息流——承載所有應用相關訊息,元件像在無管理情境下一樣訂閱與發布
- Control Bus——每個元件另外從構成控制匯流排的通道收送訊息,這些通道連向一個中央管理元件

圖 11-1:Control Bus 解法示意
控制匯流排適合承載哪些訊息#
- 組態(Configuration)——訊息流中每個元件都該有可依需要修改的參數(通道位址、訊息資料格式、逾時等)。元件透過控制匯流排從中央儲存庫取得這些資訊,而不是用屬性檔,因而有了中央組態點與執行期重新設定的能力。例如 Content-Based Router 內的路由表,可能得依系統狀況(過載或元件故障)動態更新。
- 心跳(Heartbeat)——每個元件可依指定間隔在控制匯流排上送出週期性的心跳訊息,讓中央主控台驗證它運作正常。心跳還可以帶上元件的指標,例如已處理的訊息數、機器可用記憶體等。
- 測試訊息(Test Messages)——心跳只告訴控制匯流排「元件還活著」,對「元件能否正確處理訊息」的資訊卻很有限。因此除了心跳之外,我們還可以把測試訊息注入訊息串流讓元件處理,稍後再把訊息取出,看看元件是否處理正確(這模糊了控制匯流排與訊息匯流排的界線,因此獨立成一個模式——見 Test Message)。
- 例外(Exceptions)——每個元件都能把例外狀況導向控制匯流排評估,嚴重的例外可能觸發告警通知維運人員。定義例外處理的規則應該寫在一個集中的處理器中。
- 統計(Statistics)——每個元件可以蒐集已處理訊息數、平均吞吐量、處理一則訊息的平均時間等等。有些資料可依訊息型別拆分,好判斷是否某種型別的訊息正在淹沒系統。
因為這類訊息的優先權往往低於其他訊息,控制匯流排很可能會為這種資料使用非保證送達或低優先權的通道。
- 即時主控台(Live Console)——上述多數功能都能彙整到中央主控台顯示,讓維運人員評估訊息系統的健康狀況,必要時採取修正措施。
與網路管理的類比#
Control Bus 支援的許多功能,很像用來監控與維護任何網路方案的傳統網路管理功能。它讓我們在訊息系統層級實作等價的管理功能——本質上是把它們從低階的 IP 網路層,提升到語意更豐富的訊息層。
提供這些功能對訊息基礎設施能否成功運作至關重要,但訊息方案缺乏管理標準這件事,讓「建立全企業可重用的訊息系統管理方案」變得困難。
元件的三個介面#
設計訊息處理元件時,我們圍繞三個介面來架構核心處理器:
- 入站資料介面——從訊息通道接收進站訊息
- 出站資料介面——把處理完的訊息送到出站通道
- 控制介面——與 Control Bus 之間收送控制訊息
