脈絡:一家企業有多套獨立建造的應用程式,使用不同的語言與平台。企業需要以具回應性的方式共享資料與流程。

前三種風格各缺一角#

  • 檔案傳輸共享資料庫讓應用程式共享資料,卻共享不了功能。
  • 遠端程序呼叫讓應用程式共享功能,卻在過程中把它們緊密綁在一起。

整合的挑戰常常在於:讓各自獨立的系統盡可能即時地協作,同時又不把它們綁成一團、以致在執行面或開發面都變得不可靠。

逐一檢視:

  • 檔案傳輸能讓應用程式維持極佳的解耦,代價是時效——系統之間根本跟不上彼此,協作行為慢得離譜。
  • 共享資料庫能以具回應性的方式把資料保持在一起,代價是所有東西都被耦合到資料庫,而且同樣處理不了協作行為。
  • 遠端程序呼叫看似誘人,但把「為單一應用程式設計的模型」延伸到應用整合,會撞上一大堆弱點——這些弱點始於分散式開發的本質問題。

遠端程序呼叫看起來像本地呼叫,行為卻不一樣:它更慢,而且會失敗。當企業內有多套應用程式在互相溝通時,你不會希望一個應用程式的故障拖垮其他所有應用程式;你也不希望在「呼叫很快」的假設下設計系統,更不希望每個應用程式都要知道其他應用程式的細節——哪怕只是介面的細節。

我們真正需要的東西#

  • 檔案傳輸一樣,能快速產出大量小資料封包、輕鬆傳輸,並在新封包可供消費時自動通知接收端
  • 傳輸要有重試機制確保成功
  • 儲存資料的磁碟結構或資料庫細節必須對應用程式隱藏,這樣(不同於共享資料庫)儲存 schema 與細節都能隨企業需求輕鬆改變
  • 遠端程序呼叫一樣,一個應用程式能送出資料封包去喚起另一個應用程式的行為,但不容易失敗
  • 傳輸必須是非同步的,寄件端不需要等收件端——尤其在需要重試的時候

解法#

為什麼它有效#

非同步訊息傳遞,本質上是對分散式系統諸多問題的一種務實反應。

  • 送出訊息不要求兩端同時上線就緒
  • 以非同步方式思考通訊,會強迫開發者認清「和遠端應用程式打交道比較慢」,從而鼓勵設計出高內聚(大量工作在本地完成)、低黏著(有選擇性地遠端處理)的元件。
  • 訊息系統也提供了檔案傳輸那種程度的解耦:訊息可以在傳輸途中被轉換,收發雙方都不必知道有這回事。這種解耦讓整合人員能把訊息廣播給多個接收者、從多個潛在接收者中選一個,以及其他讓「整合」與「應用程式開發」得以分離的拓樸。

由於人的因素本來就傾向把應用開發與應用整合分開,這種作法是順著人性走,而不是逆著人性走

轉換能力也意味著各應用程式可以擁有相當不同的概念模型。當然這代表語意不一致仍會發生;但從訊息傳遞的觀點看,共享資料庫為了避免語意不一致所採取的手段在實務上複雜到行不通,而且面對套裝軟體或企業合併時根本無法事後補做。

協作,而不只是共享資料#

頻繁送出小訊息,也讓應用程式除了共享資料之外還能在行為上協作。若某個流程必須在收到保險理賠時啟動,那麼單筆理賠一進來就能以一則訊息立刻啟動它;資訊也能被請求並快速獲得回覆。

這種協作當然不會像遠端程序呼叫那麼快,但呼叫端不必在訊息被處理與回覆返回的期間停下來

而且訊息傳遞並不像許多人以為的那麼慢——許多訊息方案源自金融服務業,那裡每秒有數千筆報價或交易必須穿過訊息系統。

它也不是沒有問題#

本書談的就是訊息傳遞,所以你可以合理假設作者認為它通常是企業應用整合的最佳途徑。但別以為作者覺得它毫無問題

  • 仍有延遲造成的不一致——訊息的高頻率大幅減少了折磨檔案傳輸的那些不一致問題,但沒有完全消除;系統之間並非同時更新,落差依然存在。
  • 非同步設計不是多數人被教過的方式——因此有一整套不同的規則與技巧要學。訊息傳遞的情境比在 X Windows 這類非同步應用環境中寫程式容易些,但非同步仍有學習曲線,而且測試與除錯在這種環境下更難
  • 膠水程式碼——訊息可被轉換這件事,讓應用程式之間比遠端程序呼叫與檔案傳輸解耦得多,好處明顯;但這份獨立性也意味著整合人員常得寫一大堆雜亂的膠水程式碼把所有東西湊在一起。

接下來:訊息傳遞帶出的新問題#

一旦決定用訊息傳遞來做系統整合,就有一批新議題要考慮,也有一批實踐可以採用:

  • 怎麼傳輸資料封包? 寄件端透過連接收發兩端的 Message Channel(訊息通道) 送出一則 Message(訊息)
  • 怎麼知道要送去哪? 若寄件端不知道該把資料寄到哪,可以送給 Message Router(訊息路由器),由它導向正確的接收者。
  • 怎麼知道該用什麼資料格式? 若收發雙方對格式沒有共識,寄件端可以把資料導向 Message Translator(訊息轉換器),由它轉成接收端的格式後再轉送。
  • 身為應用開發者,怎麼把應用程式接上訊息系統? 想使用訊息傳遞的應用程式會實作 Message Endpoint(訊息端點) 來執行實際的收送。