Saga pattern

Saga pattern 是用來解決分散式服務架構下各服務之間的交易資料一致性問題。


在單體服務的架構下通常會使用同一個資料庫,交易可以直接交給資料庫處理,處理失敗交易資料就會整個還原,不會有交易一致性的問題。


反觀在像微服務這樣的分散式服務的架構下,每個服務都有各自的資料儲存體,資料會被散在不同的服務身上,且商業邏輯上的交易可能需要多個服務協同完成,在這種狀況下交易的一致性無法很單純的交由資料庫處理就好。


像是假設商業邏輯上的交易要依序經過 A、B、C 三個服務,若是處理到 C 服務時失敗,C 服務的資料還原是沒什麼問題的,可直接由資料庫的交易幫我們還原資料。但是對 A、B 服務來說處理是成功的,資料庫的交易已經 Submit 了,也不會知道後面有依賴的服務處理失敗。這時就會有資料一致性的問題產生。


Saga pattern 可用來處理分散式交易或是 Long lived transaction (LLT),會定義商業邏輯上的交易依序要調用的服務,將一連串的服務交易串起。每個服務被調用時會去更新服務的資料庫,接著輪到下一個服務被調用。當錯誤發生時會對調用過的服務做補償還原,像是付過款就退款、建立了訂單就取消訂單、保留了座位就將座位釋出,用以確保資料的最終一致性。


依實作方式的不同又可細分為 Choreography 與 Orchestration 兩種模式。


Choreography 是分散式的處理方式。每一個服務處理完自行去調用下一個服務處理,每個服務自己要知道下一個要調用的服務為何。


服務之間可透過 Rest 或 RPC 直接通訊。


或是透過事件訂閱的方式。


Orchestration 是集中式的處理方式。會有一個管理中心知道商業邏輯上的交易要怎麼去調用服務,會偵測服務的處理,如果服務處理完會負責調用下一個服務,當服務處理出錯會負責調用服務去補償還原。


Saga pattern 實際應用上,為了確保服務重覆調用不會造成問題,可能在實作上得考慮賦予服務冪等(Idempotent)特性,可將交易紀錄存放起來查驗,用以忽略相同的交易觸發,以免重複調用造成重複補償。


另外協調者與服務之間或是服務彼此之間的通訊如果有丟失的可能,設計上可能需考慮是否外加 Timeout 機制,用以判定服務調用是否失敗。且需考慮是否外加背景處理機制,用以處理補償還原,確保補償還原的動作不會因協調者或服務重啟而漏處理。