架構模式: Saga
上下文
您已應用每服務數據庫模式。每個服務都有自己的數據庫。但是,某些業務事務跨越多個服務,因此您需要一種機制來確保服務之間的數據一致性。例如,假設您正在建立一個客戶有信用額度的電子商務商店。申請必須確保新訂單不會超過客戶的信用額度。由於訂單和客戶位於不同的數據庫中,因此應用程序不能簡單地使用本地ACID事務。
問題
如何跨服務維護數據一致性?
要點
- 可以不選擇2PC
結論
實現跨越多個服務的每個業務事務作為傳奇。傳奇是一系列本地交易。每個本地事務都更新數據庫並發布消息或事件以觸發saga中的下一個本地事務。如果本地事務因違反業務規則而失敗,則saga會執行一系列補償事務,以撤消先前本地事務所做的更改。
協調sage有兩種方式:
- Choreography - 每個本地事務發布觸發其他服務中的本地事務的域事件
- Orchestration - 一個orchestrator(上帝對象)告訴參與者要執行的本地事務
例子: Choreography-based saga
- Order Service創建處於掛起狀態的訂單並發布OrderCreated事件
- Customer Service收到事件嘗試為該訂單保留信用。它發布Credit Reserved事件或CreditLimitExceeded事件。
- Order Service接收事件並將訂單狀態更改為已批准或已取消
例子: Orchestration-based saga
- Order Service創建處於暫掛狀態的訂單並創建CreateOrderSaga
- CreateOrderSaga向Customer Service 發送ReserveCredit命令
- Customer Service嘗試為該訂單保留信用額並發回回復
- CreateOrderSaga接收回復並向Order Service發送ApproveOrder或RejectOrder命令
- Order Service將訂單狀態更改為已批准或已取消
結論上下文
這種模式具有以下好處:
- 它使應用程序能夠跨多個服務維護數據一致性,而無需使用分布式事務
該解決方案具有以下缺點:
- 編程模型更復雜。例如,開發人員必須設計補償事務,以明確撤消先前在saga中所做的更改。
還有以下問題需要解決:
- 為了可靠,服務必須以原子方式更新其數據庫並發布消息/事件。它不能使用跨越數據庫和消息代理的分布式事務的傳統機制。相反,它必須使用下面列出的模式之一。
關聯模式
- 每個服務獨立數據庫模式創建了對此模式的需求
- 以下模式是以原子方式更新狀態和發布消息/事件的方法:
- 事件溯源
- 交易發件箱
- 基於Choreography可以使用聚合和域事件發布事件