天天看點

【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

基于MQ的分布式事務(MQ事務最終一緻性)

方案簡介

基于MQ 的分布式事務方案其實是對本地消息表的封裝,将本地消息表基于MQ 内部,其他方面的協定基本與本地消息表一緻。

【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

本地消息表:最終一緻性

方案簡介

本地消息表的方案最初是由eBay提出,核心思路是将分布式事務拆分成本地事務進行處理。

  • 通過在事務主動發起方建立事務消息表,事務發起方處理業務和記錄事務消息在本地事務中完成,輪詢事務消息表的資料發送事務消息,事務被動方基于消息中間件消費事務消息表中的事務。
  • 這樣設計可以避免”業務處理成功 + 事務消息發送失敗",或"業務處理失敗 + 事務消息發送成功"的棘手情況出現,保證 2 個系統事務的資料一緻性。
處理流程
  • 把分布式事務最先開始處理的事務方稱為事務主動方
  • 在事務主動方之後處理的業務内的其他事務稱為事務被動方。
下面繼續以電商下單為例進行方案解析,這裡把整個過程簡單分為扣減庫存,訂單建立 2 個步驟。
  1. 庫存服務和訂單服務分别在不同的伺服器節點上,其中庫存服務是事務主動方,訂單服務是事務被動方。
  2. 事務的主動方需要建立事務消息表,用于記錄分布式事務的消息的發生、處理狀态。

事務發起

【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

事務回調

【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

事務分布流程

步驟1-事務主動方處理本地事務。

  • 事務主動方在本地事務中處理業務更新操作和寫消息表操作。
例:庫存服務階段在本地事務中完成扣減庫存和寫消息表

步驟 2-事務主動方通過消息中間件,通知事務被動方處理事務通知事務待消息。

  • 消息中間件可以基于 Kafka、RabbitMQ 消息隊列,事務主動方主動寫消息到消息隊列,事務消費方消費并處理消息隊列中的消息。
例:庫存服務把事務待處理消息寫到消息中間件,訂單服務消費消息中間件的消息,完成新增訂單

步驟 3-事務被動方通過消息中間件,通知事務主動方事務已處理的消息。

  • 為了資料的一緻性,當處理錯誤需要重試,事務發送方和事務接收方相關業務處理需要支援幂等。
例,訂單服務把事務已處理消息寫到消息中間件,庫存服務消費中間件的消息,并将事務消息的狀态更新為已完成

儲存一緻性的容錯處理

步驟 1 處理出錯

事務復原,相當于什麼都沒發生。

步驟2+步驟3處理出錯

由于未處理的事務消息還是儲存在事務發送方,事務發送方可以定時輪詢為逾時消息資料,再次發送到消息中間件進行處理。事務被動方消費事務消息重試處理。
  • 如果業務上的失敗,事務被動方可以發消息給事務主動方進行復原。
  • 如果多個事務被動方已經消費消息,事務主動方需要復原事務時需要通知事務被動方復原。

方案總結

方案的優點

  • 從應用設計開發的角度實作了消息資料的可靠性,消息資料的可靠性不依賴于消息中間件,弱化了對 MQ 中間件特性的依賴。
  • 方案輕量,容易實作。

方案的缺點

  1. 與具體的業務場景綁定,耦合性強,不可公用。
  2. 消息資料與業務資料同庫,占用業務系統資源。
  3. 業務系統在使用關系型資料庫的情況下,消息服務性能會受到關系型資料庫并發性能的局限。

基于RocketMQ的分布式事務(資料的最終一緻性)

基于RocketMQ4.3之後的版本介紹 MQ 的分布式事務方案。

在本地消息表方案中,保證事務主動方發寫業務表資料和寫消息表資料的一緻性是基于資料庫事務,RocketMQ的事務消息相對于普通 MQ,相對于提供了 2PC 的送出接口,方案如下:
【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)
正常情況:事務主動方發消息
【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

事務主動方服務正常,沒有發生故障,發消息流程如下:

  1. 發送方向 MQ 服務端(MQ Server)發送 half 消息。
  2. MQ Server 将消息持久化成功之後,向發送方 ack 确認消息已經發送成功。
  3. 發送方開始執行本地事務邏輯。
  4. 發送方根據本地事務執行結果向MQ Server 送出二次确認(commit 或是 rollback)。
  5. MQ Server 收到 commit 狀态則将半消息标記為可投遞,訂閱方最終将收到該消息;MQ Server 收到 rollback 狀态則删除半消息,訂閱方将不會接受該消息。
異常情況:事務主動方消息恢複
【分布式技術專題】「架構實踐于案例分析」總結和盤點目前常用分布式事務特别及問題分析(中)

在斷網或者應用重新開機等異常情況下,第四步送出的二次确認逾時未到達 MQ Server,此時處理邏輯如下:

  1. MQ Server 對該消息發起消息回查。
  2. 發送方收到消息回查後,需要檢查對應消息的本地事務執行的最終結果。
  3. 發送方根據檢查得到的本地事務的最終狀态再次送出二次确認。
  4. MQ Server基于 commit/rollback 對消息進行投遞或者删除。
  • 事務主動方基于MQ通信通知事務被動方處理事務,事務被動方基于 MQ 傳回處理結果。
  • 事務被動方消費消息異常,需要不斷重試,業務處理邏輯需要保證幂等。
  • 事務被動方業務上的處理失敗,可以通過 MQ 通知事務主動方進行補償或者事務復原。

方案總結

相比本地消息表方案,MQ 事務方案優點是:
  1. 消息資料獨立存儲 ,降低業務系統與消息系統之間的耦合。
  2. 吞吐量優于使用本地消息表方案。
缺點
  • **一次消息發送需要兩次網絡請求(half 消息 + commit/rollback 消息) **。
  • 業務處理服務需要實作消息狀态回查接口。