微服務–分布式事務的實現方法及替代方案
概念澄清
柔性事務 vs. 剛性事務
剛性事務是指嚴格遵循acid原則的事務, 例如單機環境下的資料庫事務.
柔性事務是指遵循base理論的事務, 通常用在分布式環境中, 常見的實現方式有: 兩階段提交(2pc), tcc補償型提交, 基於訊息的非同步確保型, 最大努力通知型.
通常對本地事務採用剛性事務, 分布式事務使用柔性事務.
最佳實踐
先上結論, 再分別介紹分布式事務的各種實現方式.
如果業務場景需要強一致性, 那麼盡量避免將它們放在不同服務中, 也就是盡量使用本地事務, 避免使用強一致性的分布式事務.
如果業務場景能夠接受最終一致性, 那麼最好是使用基於訊息的最終一致性的方案(非同步確保型)來解決.
如果業務場景需要強一致性, 並且只能夠進行分布式服務部署, 那麼最好是使用tcc方案而不是2pc方案來解決.
注意: 以下每種方案都有不同的適用場合, 需要根據實際業務場景來選擇.
兩階段提交(2pc)
兩階段提交(two phase commit, 2pc), 具有強一致性, 是cp系統的一種典型實現.
兩階段提交, 常見的標準是xa, jta等. 例如oracle的資料庫支援xa.
下圖是兩階段提交的示意圖:
缺點兩階段提交中的第二階段, 協調者需要等待所有參與者發出yes請求, 或者乙個參與者發出no請求後, 才能執行提交或者中斷操作. 這會造成長時間同時鎖住多個資源, 造成效能瓶頸, 如果參與者有乙個耗時長的操作, 效能損耗會更明顯.
實現複雜, 不利於系統的擴充套件, 不推薦.
tcc (try-confirm-cancle)
tcc, 是基於補償型事務的ap系統的一種實現, 具有最終一致性.
下面以客戶購買商品時的付款操作為例進行講解:
try:
完成所有的業務檢查(一致性),預留必須業務資源(準隔離性);
體現在本例中, 就是確認客戶賬戶餘額足夠支付(一致性), 鎖住客戶賬戶, 商戶賬戶(準隔離性).
confirm:
使用try階段預留的業務資源執行業務(業務操作必須是冪等的), 如果執行出現異常, 要進行重試.
在這裡就是執行客戶賬戶扣款, 商戶賬戶入賬操作.
cancle:
釋放try階段預留的業務資源, 在這裡就是釋放客戶賬戶和商戶賬戶的鎖;
如果任一子業務在confirm階段有操作無法執行成功, 會造成對業務活動管理器的響應超時, 此時要對其他業務執行補償性事務. 如果補償操作執行也出現異常, 必須進行重試, 若實在無法執行成功, 則事務管理器必須能夠感知到失敗的操作, 進行log(用於事後人工進行補償性事務操作或者交由中介軟體接管在之後進行補償性事務操作).
優點對比與前面提到的兩階段提交法, 有兩大優勢:
tcc能夠對分布式事務中的各個資源進行分別鎖定, 分別提交與釋放, 例如, 假設有ab兩個操作, 假設a操作耗時短, 那麼a就能較快的完成自身的try-confirm-cancel流程, 釋放資源. 無需等待b操作. 如果事後出現問題, 追加執行補償性事務即可.
tcc是繫結在各個子業務上的(除了cancle中的全域性回滾操作), 也就是各服務之間可以在一定程度上"非同步並行"執行.
注意事項
事務管理器(協調器)這個節點必須以帶同步複製語義的高可用集群(hac)方式部署.
事務管理器(協調器)還需要使用多數派演算法來避免集**生腦裂問題.
適用場景
嚴格一致性
執行時間短
實時性要求高
舉例: 紅包, 收付款業務.
非同步確保型
通過將一系列同步的事務操作變為基於訊息執行的非同步操作, 避免了分布式事務中的同步阻塞操作的影響.
這個方案真正實現了兩個服務的解耦, 解耦的關鍵就是非同步訊息和補償性事務.
這裡以乙個例子作為講解:
非同步確保型
執行步驟如下:
mq傳送方傳送遠端事務訊息到mq server;
mq server給予響應, 表明事務訊息已成功到達mq server.
mq傳送方commit本地事務.
若本地事務commit成功, 則通知mq server允許對應事務訊息被消費; 若本地事務失敗, 則通知mq server對應事務訊息應被丟棄.
若mq傳送方超時未對mq server作出本地事務執行狀態的反饋, 那麼需要mq servfer向mq傳送方主動回查事務狀態, 以決定事務訊息是否能被消費.
當得知本地事務執行成功時, mq server允許mq訂閱方消費本條事務訊息.
需要額外說明的一點, 就是事務訊息投遞到mq訂閱方後, 並不一定能夠成功執行. 需要mq訂閱方主動給予消費反饋(ack)
如果mq訂閱方執行遠端事務成功, 則給予消費成功的ack, 那麼mq server可以安全將事務訊息移除;
如果執行失敗, mq server需要對訊息重新投遞, 直至消費成功.
注意事項
訊息中介軟體在系統中扮演乙個重要的角色, 所有的事務訊息都需要通過它來傳達, 所以訊息中介軟體也需要支援 hac 來確保事務訊息不丟失.
根據業務邏輯的具體實現不同,還可能需要對訊息中介軟體增加訊息不重複, 不亂序等其它要求.
適用場景
執行週期較長
實時性要求不高
例如:跨行轉賬/匯款業務(兩個服務分別在不同的銀行中)
退貨/退款業務
財務, 賬單統計業務(先傳送到訊息中介軟體, 然後進行批量記賬)
最大努力通知型
這是分布式事務中要求最低的一種, 也可以通過訊息中介軟體實現, 與前面非同步確保型操作不同的一點是, 在訊息由mq server投遞到消費者之後, 允許在達到最大重試次數之後正常結束事務.
適用場景
交易結果訊息的通知等.
小結不管是同步事務中的事務管理器(協調者), 還是非同步事務中使用的訊息中介軟體,若要達到一致性保證,都需要使用帶有同步複製語義的 hac 提供的高可用和高可靠特性,這些都是以效能為代價的,無疑成為了soa 架構中的典型效能瓶頸之一.
MQ 分布式事務 微服務應用
以支付 電商下單為例子。乙個電商系統包含了好幾大類模組,就比如有使用者模組 商品模組 庫存模組 訂單模組 支付模組 物流模組,活動模組等,以下就先列舉幾個最基礎常見的模組 使用者模組 商品模組 庫存模組 訂單模組 支付模組 使用者流程如下 如果系統規模較小,資料表都在乙個資料庫例項上,專案服務端也都...
分布式事務 分布式事務的實現
如果在多個服務中需要對不同的資料庫進行操作。因為不同服務操作的資料庫都不同,所以保證在同乙個事務中完成操作顯然是不科學的。那實現分布式事務的思想 1 方法入口,建立一條日誌記錄,狀態定義為初始狀態,即儲存本條日誌記錄 可以儲存在資料庫中,也可以寫出到本地磁碟檔案 2 可以在非同步執行緒或在定時任務中...
微服務架構及分布式事務解決方案
分布式事務場景如何設計系統架構及解決資料一致性問題,個人理解最終方案把握以下原則就可以了,那就是 大事務 小事務 原子事務 非同步 訊息通知 解決分布式事務的最好辦法其實就是不考慮分布式事務,將乙個大的業務進行拆分,整個大的業務流程,轉化成若干個小的業務流程,然後通過設計補償流程從而考慮最終一致性。...