基於RabbitMQ消息隊列的分佈式事務解決方案 - MQ分佈式消息中間件實戰

美團配送系統架構演進實踐

1 極速瞭解MQ

介紹Rabbitmg用於解決分佈式事務必須掌握的5個核心概念html

一款分佈式消息中間件,基於erlang語言開發, 具有語言級別的高併發處理能力。和Spring框架是同一家公司。
支持持久化、高可用算法

核心5個概念:

  1. Queue: 真正存儲數據的地方
  2. Exchange: 接收請求,轉存數據
  3. Bind: 收到請求後存儲到哪裏
  4. 消息生產者:發送數據的應用
  5. 消息消費者: 取出數據處理的應用

二、分佈式事務問題

分佈式事務是一個業務問題,不能脫離具體的場景。數據庫

2.1 分佈式事務的幾種解決方案

● 基於數據庫XA/ JTA協議的方式
須要數據庫廠商支持; JAVA組件有atomikos等
● 異步校對數據的方式
支付寶、微信支付主動查詢支付狀態、對帳單的形式;
● 基於可靠消息(MQ)的解決方案
異步場景;通用性較強;拓展性較高
● TCC編程式解決方案
嚴選、阿里、螞蟻金服本身封裝的DTX編程

本文目標:針對全部人羣,學會基於可靠消息來解決分佈式事務問題。
分佈式事務的解決方案,業務針對性很強,重要的是思路,而不是照搬微信

  • 美團點評系統架構

2.2 多系統間的分佈式事務問題

  • 用戶下單生成訂單
  • 須要傳遞訂單數據,由此產生兩個事務一致性問題

錯誤的案例

當接口調用失敗時,訂單系統事務回滾,提示用戶操做失敗

誤覺得這樣的接口調用寫法,就不會有分佈式事務問題架構

接口調用成功或者失敗,都會產生分佈式事務問題:

  1. 接口調用成功,訂單系統數據庫事務提交失敗,運單系統沒有回滾,產生數據
  2. 接口調用超時,訂單系統數據庫事務回滾,運單系統接口繼續執行,產生數據

上述兩種狀況,都會致使數據不一致的問題併發

三、實現分佈式事務 - 五步法

經過MQ解決分佈式事務的5個步驟, 以及分佈式事務處理中要注意的地方框架

  • 以前都是訂單系統發送HTTP請求運單系統的接口,出問題了!
  • 所以咱們考慮發消息給MQ, 異步暫存!

3.1 總體設計思路


外賣下訂單後,能夠慢慢等待運單中心數據生成,並不是強制要求同時性運維

  1. 可靠生產:保證消息必定要發送到Rabitmq服務
  2. 可靠消費:保證消息取出來必定正確消費掉

最終使多方數據達到一致。異步

3.2 步驟1 - 可靠的消息生產記錄消息發送

  • 存在隱患 - 可能消息發送失敗呀!

爲了確保數據必定成功發送到MQ。
在同一事務中,增長一個記錄表的操做, 記錄每一條發往MQ的數據以及它的發送狀態
因而咱們在訂單系統中增長一個本地信息表

因而在代碼實踐中,再也不經過HTTP接口調用運單系統接口,而是使用MQ

生成訂單時,也保存本地信息表


3.3 步驟2 - 可靠消息生產(修改消息發送狀態)

  • 利用RabbitMQ事務發佈確認機制(confirm)
    開啓後,MQ準確受理消息會返回回執

  • 而後就能知道如何更新本地信息表了

-確保在SB中開啓Confirm機制


  • 若是出現回執沒收到、消息狀態修改失敗等特殊狀況
    兜底方案:定時檢查消息表,超時沒發送成功,再次重發

3.4 步驟3 - 可靠消息處理(正常處理)

  • 運單系統收到消息數據後,忽然宕機,或者訪問運單DB時,DB忽然宕機,消息數據不就丟了嗎!!!

因而須要如下特性:

冪等性
防止重複消息數據的處理,一次用戶操做,只對應一次數據處理

開啓手動ACK模式
由消費者控制消息的重發/清除/丟棄

3.5 步驟4 - 可靠消息處理(消息重發)


消費者處理失敗,須要MQ再次重發給消費者。
出現異常通常會重試幾回,由消費者自身記錄重試次數,並進行次數控制(不會永遠重試!)

3.6 步驟五 - 可靠消息處理(消息丟棄)

消費者處理失敗,直接丟棄或者轉移到死信隊列(DLQ)
重試次數過多、消息內容格式錯誤等狀況,經過線上預警機制通知運維人員

4 總結及擴展

4.1 MQ方案的優勢和缺點

口優勢

  1. 通用性強
  2. 拓展性強
  3. 方案成熟

口缺點

  1. 基於消息中間件,只適合異步場景
  2. 消息處理會有延遲,須要業務上可以容忍

儘可能避免分佈式事務;
儘可能將非核心事務作成異步;

4.2 拓展

分佈式事務解決方案的理論依據

CAP理論BASE理論2PC協議3PC協議Paxos算法.Raft一致性協議

相關文章
相關標籤/搜索