要監控的對象#
貸款仲介的實作由四個關鍵元件組成:
- Test Client——發出貸款報價請求
- Loan Broker——扮演中央流程管理器,協調信用機構與各銀行之間的通訊
- Credit Bureau——為 Loan Broker 提供服務,計算客戶的信用分數
- Bank——各家銀行從 Loan Broker 收到報價請求,依貸款參數提交利率報價
在這個限制下,管理方案要滿足四項需求:
- 管理主控台——單一前端,顯示所有元件的健康狀況,並讓我們在出事時採取補償措施
- 貸款仲介的服務品質——原方案中由測試客戶端監控「請求到回應」的回應時間;在真實正式環境中客戶端不會替我們做這件事(他們只會抱怨系統太慢),因此管理方案必須自己捕捉這項資訊並轉給主控台
- 驗證信用機構的運作——Credit Bureau 是第三方提供的外部服務,我們要定期送測試訊息確保它正確運作
- 信用機構的容錯移轉——Credit Bureau 故障時,我們要暫時把信用請求訊息改導向另一家服務提供者

圖 12-1:Loan Broker 的四個關鍵元件
管理主控台#
我們要在單一個點蒐集多個元件的指標,從一處評估整體方案的健康狀況;主控台也必須能控制訊息流與元件參數,好在故障時透過重新路由訊息或改變元件行為來因應。
主控台透過訊息與各元件通訊,使用一條獨立的 Control Bus——上面只有系統管理相關的訊息,沒有應用資料。
因為這是一本談企業整合、而非使用者介面設計的書,主控台做得非常、非常簡單。許多廠商提供即時資料顯示,你甚至能用 Visual Basic 與 Excel 做出視覺奇蹟;許多作業系統或程式平台也提供自己的監測框架(Java 的 JMX、Microsoft 的 WMI)。
作者選擇手工打造,好讓方案不那麼依賴特定廠商 API,也展示監控方案的內部運作。

圖 12-10:管理主控台內部的事件傳播
需求一:用 Smart Proxy 測量服務品質#
第一項需求是測量 Loan Broker 提供給客戶的服務品質。這種監控不關心個別訊息的商業內容(提供給客戶的利率),只關心請求與回覆訊息之間所經過的時間。
棘手之處在於:客戶可以用 Return Address 指定回覆訊息的通道,因此我們無法在固定通道上監聽回覆。
插入方式對客戶透明#
我們把 Smart Proxy「插」在客戶與 Loan Broker 之間:
- Smart Proxy 監聽 Loan Broker 原本監聽的那個通道(
loanrequestQueue),因此這次插入對客戶是透明的 - 重新啟動 Loan Broker 並給它新參數,讓它改監聽
brokerRequestQueue - Smart Proxy 指示 Loan Broker 把所有回覆送到
brokerReplyQueue,再由它從那裡轉送回正確的 Return Address

圖 12-2:用 Smart Proxy 為 Loan Broker 加裝監測
測量什麼#
- 回應時間——Smart Proxy 記下收到請求訊息的時間,收到對應回覆時用當前時間減去請求時間
- 同時處理中的請求數——計算「尚未收到回覆的請求訊息」有多少
Smart Proxy 無法區分「排在
brokerRequestQueue上的訊息」與「Loan Broker 已開始處理的訊息」,因此這個指標等於兩者的總和。每收到一則請求或回覆訊息時就更新這個數字。
別把網路塞爆#
我們可以為每一則訊息都送出統計,但訊息量一大就會塞爆網路。而且把 Smart Proxy 插入訊息流本身就已經讓訊息數量翻倍(請求與回覆各兩則),所以我們不想再為每則請求多送一則控制訊息。
改用計時器:讓 Smart Proxy 每隔預定間隔(例如 5 秒)才送一則指標訊息到 Control Bus。
指標訊息可以裝摘要指標(最大、最小、平均回應時間),也可以裝該區間內所有訊息的詳細資訊。為了讓指標訊息小、主控台簡單,我們決定只傳摘要指標。
實作上重用了 Smart Proxy 模式中的基底類別,把
SmartProxyBase、SmartProxyRequestConsumer與SmartProxyReplyConsumer各自子類別化。

圖 12-3:Loan Broker Smart Proxy 類別圖

圖 12-4:Loan Broker Smart Proxy 的統計數據
需求二:用測試訊息驗證信用機構#
第二項需求是監控外部 Credit Bureau 服務的正確運作。
我們定期送 Test Message 給該服務。因為 Credit Bureau 支援 Return Address,注入測試訊息很容易、也不會干擾既有訊息流——我們只要為測試訊息提供一個專用的回覆通道,就不需要另外做測試訊息分離器。
測試資料產生器與驗證器#
- Test Data Generator——Credit Bureau 的測試訊息很簡單,唯一必要欄位是社會安全號碼(SSN)。我們用一個代表虛構人物的特殊固定 SSN,好用預先確立的結果驗證回覆資料——這樣不只能檢查「有沒有收到回覆」,還能驗證訊息內容。
- Test Data Verifier——本例中 Credit Bureau 被寫成不論 SSN 為何都回傳隨機結果,因此驗證器不檢查特定值,而是驗證結果是否落在允許範圍內(例如信用分數 300–900)。若落在範圍外(例如計算錯誤讓分數變成 0),驗證器就送訊息通知主控台。
驗證器也檢查外部服務的回應時間:若在預設時間內沒收到回覆,就向主控台告警。
唯一的例外是:在偵測到錯誤之後又收到正確回覆時,監控器會送一則「服務正常」訊息,指出信用機構又恢復正常了。
另外,監控器啟動時會送一則訊息向主控台宣告自己的存在——這讓主控台能「發現」所有活躍的監控器,並顯示各自的狀態。

圖 12-5:監控 Credit Bureau 服務
兩個計時器#
監控器的實作使用兩個獨立計時器:
- Send Timer——決定「上次收到訊息或上次逾時事件」到「送出下一則測試訊息」之間的間隔
- Timeout Timer——每當監控器送出請求訊息就啟動。回覆在指定逾時間隔內抵達,就重設它並隨下一則請求重新啟動;若沒收到,逾時計時器就觸發,監控器向控制匯流排送出錯誤訊息,接著啟動新的 Send Timer 以便在送出間隔後發起新請求
監控器的實作相當簡單,只需要一個類別:
Monitor繼承自 Smart Proxy 模式中引入的MessageConsumer——後者設定入站通道並啟動一個 Event-Driven Consumer,繼承類別只要覆寫虛擬的ProcessMessage方法就能加上自己的處理。

圖 12-6:監控器的兩個計時器
需求三:信用機構的容錯移轉#
能監控信用機構的狀態之後,我們要用這些資料實作容錯移轉,讓 Loan Broker 在 Credit Bureau 故障時仍能繼續運作。
為什麼需要「明確的」容錯移轉#
值得注意的是:Point-to-Point Channel 本身就已提供一種基本的容錯移轉——當單一個點對點通道上有多個 Competing Consumers 時,只要還有其他消費者在運作,其中一個故障也不會中斷處理;而多個消費者活躍時它們會分攤負載,實際上實作了簡單的負載平衡。
那為什麼還需要明確的容錯移轉機制?
- 使用外部服務時,我們可能被限制在不支援 Competing Consumers 的簡單通道上(例如 SOAP over HTTP)
- 我們也未必想讓多個服務做負載平衡:例如我們可能與主要服務提供者有量約協議,達到一定用量配額能拿到可觀折扣——把流量拆給兩家提供者很可能反而更貴
- 又或者我們用低價提供者當主要服務,只在它故障時才切換到高價提供者
用情境式路由器實作#
作法是在信用機構的請求通道中插入一個 Message Router,由它把請求路由到主要或次要的信用機構服務。
- 因為次要服務可能使用不同的訊息格式,我們用一對 Message Translator 把它包起來
- 這個 Message Router 是一個 Context-Based Router,由管理主控台透過 Control Bus 控制
- 主控台從前一節設計的 Credit Bureau 監控器取得監控資料;監控器指出故障時,主控台就指示路由器把流量改導向次要提供者
方案圖中沒有畫次要提供者的監控器,但要用第二個信用機構監控器實例去監控備援服務其實非常容易。

圖 12-7:以 Context-Based Router 實作明確的容錯移轉

圖 12-8:管理主控台顯示兩個 Credit Bureau 服務皆為活躍

圖 12-9:管理主控台偵測到主要 Credit Bureau 服務失效
本範例的限制#
為了把這個範例塞進單一章,我們做了一些簡化假設。
容錯移轉沒有處理已排隊的訊息#
Loan Broker 因為會把進站回應與回覆訊息關聯起來,所以仍能繼續運作;但與那些「卡住訊息」相關的貸款報價請求,要等主要 Credit Bureau 回來才會被處理。
要改善容錯移轉情境下的回應時間,有兩種作法:
- 實作重送功能,讓 Loan Broker 為「無限期卡在故障服務前面」的訊息重新發出請求
- 或讓容錯移轉路由器保存「自上次確認服務正常以來所有抵達的請求訊息」,偵測到故障時就把它們全部重送——因為其中有些可能沒被正確處理
後者可能造成重複的請求(與對應的回覆)訊息,但因為 Credit Bureau 服務與 Loan Broker 都是 Idempotent Receiver,這不會造成問題——重複的回覆訊息會直接被忽略。
只示範了一小部分#
這個範例只示範了「用本章模式可實作之系統管理功能」的一小部分。我們還能監控所有元件的訊息流量、設定效能門檻、讓每個元件送出心跳訊息……
事實上,替一套分散式訊息方案加上健全的系統管理,所需的設計與實作工夫可能與原方案本身一樣多,甚至更多。