方案 |
解決思路 |
適用場景 |
說明 |
本地事務 |
- 基於數據庫的ACID理論
- 基於undo、redo日誌記錄
- undo日誌實現回滾、redo日誌實現commit場景異常的恢復
|
- 傳統單體架構
- 分佈式事務要求不高的場景
|
- 分佈式系統場景出現問題怎麼辦?
- 日誌記錄--監控告警–人工干預修復
- 問題溯源,例如:維修工單能夠建立,可是維修費用調用失敗致使整個事務回滾
- 可能維修費用自身問題,如性能壓力過大致使請求時,觸發調用失敗回滾
- 可能維修費用操做依據成功了,可是返回
|
兩階段提交 |
- 基於XA協議,依賴TM、RM的交互,依賴數據庫的能力
- TM存在單點故障,鎖資源佔用時間較長
|
- 面向多數據源或者分佈式數據庫設計(XA本質是TM與RM之間的規範)
- 適用於多數據源的架構
- Mycat也實現了XA協議,一些公司的分佈式事務使用該方案,可是應用層非微服務架構
- 適用於併發量不大,處理時間較短的核心交易業務場景
|
- XA協議:
|
三階段提交 |
- 基於TCC協議
- 在數據庫外部實現事務機制達到最終一致性
- 犧牲了應用的靈活性,須要提供Try、Confirm、Cancel的具體實現,且須要當心保證冪等操做
|
- 跨應用,但須要實現TCC接口,對已有系統侵入較大,適用於新系統
- 不強依賴數據庫特性,TCC是一個通用的模型
- 參考實現:https://github.com/liuyangming/ByteTCC/
|
- TCC協議:
|
可靠消息模式 |
- 大事務轉變爲小事務,小事物之間的不一致經過額外的輪訓任務進行補償
-
-
可分爲基於本地事件、基於外部事件兩種模式
- 業務邏輯須要保證冪等性
|
- 適用於核心模塊的改造,或者徹底基於消息驅動的架構,不然對已有系統入侵較大
- 另外,若是須要回滾,超過兩個實務操做的場景比較複雜,因此這種場景須要遵照最終一致性原則,失敗不會滾,直到補償成功
- 依賴具有事務功能的消息系統或者數據庫,如:RabbitMQ、Kafka、RocketMQ等
|
- 基於本地事件:
- 基於外部事件:
|
可靠消息變種 |
- 不依賴消息隊列通訊,將消息隊列的功能包裝爲Rest服務,屏蔽消息隊列的接口
- 將基於可靠消息模式對架構和應用入侵的缺點下降
|
- 最大努力通知型
- 如支付寶的回調機制,能夠設置指數時間重試,參考阿里實現:https://zhuanlan.zhihu.com/p/26114119
|
|
- 下游應用輪詢
- 如微信的輪詢機制,由下游應用本身保證一致性
|
|
SAGA方案 |
- 基於工做流的思路,原理:https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
- 定義順序操做、回滾操做的流程,交給事務協調器統一管理
- 一些應用框架實現了該方案,如CQRS框架Axonframework:https://github.com/AxonFramework/AxonFramework,又如華爲servicecomb:https://github.com/apache/incubator-servicecomb-saga
|
- 應用方定義工做流,交給SAGA進行管理,雖然這種方案不火熱,可是對應用入侵較小,且符合分層的設計原則,添加一個composite層單獨實現須要分佈式事務的流程便可
|
- SAGA工做流:
|
阿里GTS |
- 優化XA架構的路線,使用上與XA相似,業務入侵較小,添加註解
- GTS參考:https://zhuanlan.zhihu.com/p/32684212
- 仿GTS實現:https://github.com/wxbty/meepo
https://github.com/chenjy16/gts
- 與GTS相似的:https://github.com/codingapi/tx-lcn 看起來最成熟的開源方案
|
- 適用於阿里雲方案,專線也能夠接入使用,第三方系統遵循TCC的也能夠接入
|
|
總結建議 |
- 若是非必要,不引入分佈式事務,每一個微服務保證自身的高可用,基本可以保證數據的一致性,極端的狀況除外。--事實上微服務的架構BAT十年前就在使用,沒有分佈式事務也同樣,由於基礎設施、每一個微服務自身可用性比較高,因此不須要引入更大的複雜性
- 若是必要,首先保證核心業務的數據一致性,好比交易業務,能夠採用消息機制、最大努力通知、輪詢機制的方案,他們的本質都是記帳,即便出了問題也有據可查--這部分通常藉助第三方支付系統的能力便可知足
- 若是隻是較少許的業務須要分佈式事務特性,能夠局部使用基於可靠消息的方案,參考:https://github.com/vvsuperman/coolmq,這種方案須要注意不少細節,理論上每一個環節均可能出現網絡異常,都須要有相應的措施保障,好比:若是創建指數時間重試機制,下游服務接口須要保證冪等,該方案至關於業務本身負責維護一致性
- 若是大量業務須要分佈式事務,也能夠引入相似DelayMq的服務作解耦,利用該服務提供回調服務將服務鏈串聯起來(消息中包含回調的Url、參數),可是下游的服務接口須要保證冪等性--PaaS平臺能夠提供相似的服務,參考:https://zhuanlan.zhihu.com/p/26114119。該方案須要可以接受部分代碼的重構
- 若是大量業務須要分佈式事務,能夠引入相似GTS對業務入侵較小的框架,避免更新架構和代碼,代碼添加必要的註解便可,如:https://github.com/codingapi/tx-lcn --開源方案,建議通過測試以後謹慎上線,這個能力也能夠研究下看看能不能作到PaaS平臺
- 數據一致性是一個系統工程,僅僅在事務框架層面解決是不夠的,還須要配套的規範措施--如請求RequestID、鏈路追蹤、接口冪等、日誌輸出規範、關鍵日誌記錄規範等,出現問題能夠快速定位,這部分的數據可讓PaaS接管,提供鏈路服務、監控告警服務等
- 完善基礎設施,下降網絡問題的影響是重要前提。對於實際調用已經成功,返回時網絡異常的問題,須要補償機制--PaaS能夠提供相似DelayMq的服務
- 完善應用的監控告警設施,如應用的API、訪問次數、失敗次數等監控,及時告警--PaaS能夠提供應用的實時監控告警能力
|