美團配送系統架構演進實踐
1 極速了解MQ
介紹Rabbitmg用於解決分布式事務必須掌握的5個核心概念
一款分布式消息中間件,基於erlang語言開發, 具備語言級別的高並發處理能力。和Spring框架是同一家公司。
支持持久化、高可用
核心5個概念:
- Queue: 真正存儲數據的地方
- Exchange: 接收請求,轉存數據
- Bind: 收到請求后存儲到哪里
- 消息生產者:發送數據的應用
- 消息消費者: 取出數據處理的應用
2、分布式事務問題
分布式事務是一個業務問題,不能脫離具體的場景。
2.1 分布式事務的幾種解決方案
● 基於數據庫XA/ JTA協議的方式
需要數據庫廠商支持; JAVA組件有atomikos等
● 異步校對數據的方式
支付寶、微信支付主動查詢支付狀態、對賬單的形式;
● 基於可靠消息(MQ)的解決方案
異步場景;通用性較強;拓展性較高
● TCC編程式解決方案
嚴選、阿里、螞蟻金服自己封裝的DTX
本文目標:針對所有人群,學會基於可靠消息來解決分布式事務問題。
分布式事務的解決方案,業務針對性很強,重要的是思路,而不是照搬
- 美團點評系統架構
2.2 多系統間的分布式事務問題
- 用戶下單生成訂單
- 需要傳遞訂單數據,由此產生兩個事務一致性問題
錯誤的案例
當接口調用失敗時,訂單系統事務回滾,提示用戶操作失敗
誤以為這樣的接口調用寫法,就不會有分布式事務問題
接口調用成功或者失敗,都會產生分布式事務問題:
- 接口調用成功,訂單系統數據庫事務提交失敗,運單系統沒有回滾,產生數據
- 接口調用超時,訂單系統數據庫事務回滾,運單系統接口繼續執行,產生數據
上述兩種情況,都會導致數據不一致的問題
3、實現分布式事務 - 五步法
通過MQ解決分布式事務的5個步驟, 以及分布式事務處理中要注意的地方
- 之前都是訂單系統發送HTTP請求運單系統的接口,出問題了!
- 因此我們考慮發消息給MQ, 異步暫存!
3.1 整體設計思路
外賣下訂單后,可以慢慢等待運單中心數據生成,並非強制要求同時性
- 可靠生產:保證消息一定要發送到Rabitmq服務
- 可靠消費:保證消息取出來一定正確消費掉
最終使多方數據達到一致。
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方案的優點和缺點
口優點
- 通用性強
- 拓展性強
- 方案成熟
口缺點
- 基於消息中間件,只適合異步場景
- 消息處理會有延遲,需要業務上能夠容忍
盡量避免分布式事務;
盡量將非核心事務做成異步;
4.2 拓展
分布式事務解決方案的理論依據
CAP理論
BASE理論
2PC協議
3PC協議
Paxos算法.
Raft一致性協議