微服務分佈式事務的實現方法及替代方案

微服務–分佈式事務的實現方法及替代方案

這兩天正在研究微服務架構中分佈式事務的處理方案, 作一個小小的總結, 做爲備忘. 若有錯誤, 歡迎指正!算法

概念澄清

  • 事務補償機制: 在事務鏈中的任何一個正向事務操做, 都必須存在一個徹底符合回滾規則的可逆事務.
  • CAP理論: CAP(Consistency, Availability, Partition Tolerance), 闡述了一個分佈式系統的三個主要方面, 只能同時擇其二進行實現. 常見的有CP系統, AP系統.
  • 冪等性: 簡單的說, 業務操做支持重試, 不會產生不利影響. 常見的實現方式: 爲消息額外增長惟一ID.
  • BASE(Basically avaliable, soft state, eventually consistent): 是分佈式事務實現的一種理論標準.

柔性事務 vs. 剛性事務

剛性事務是指嚴格遵循ACID原則的事務, 例如單機環境下的數據庫事務.數據庫

柔性事務是指遵循BASE理論的事務, 一般用在分佈式環境中, 常見的實現方式有: 兩階段提交(2PC), TCC補償型提交, 基於消息的異步確保型, 最大努力通知型.安全

一般對本地事務採用剛性事務, 分佈式事務使用柔性事務.架構

先上結論, 再分別介紹分佈式事務的各類實現方式.異步

  • 若是業務場景須要強一致性, 那麼儘可能避免將它們放在不一樣服務中, 也就是儘可能使用本地事務, 避免使用強一致性的分佈式事務.
  • 若是業務場景可以接受最終一致性, 那麼最好是使用基於消息的最終一致性的方案(異步確保型)來解決.
  • 若是業務場景須要強一致性, 而且只可以進行分佈式服務部署, 那麼最好是使用TCC方案而不是2PC方案來解決.

注意: 如下每種方案都有不一樣的適用場合, 須要根據實際業務場景來選擇.分佈式

 

1、最佳實踐型

    儘可能避免將一個事務放在不一樣服務中, 也就是儘可能使用本地事務, 避免使用強一致性的分佈式事務,每一個微服務理論上只返回結果,這是最優方法。固然避免不了出現事務在不一樣的微服務中,請使用下面方法。微服務

2、兩階段提交(2PC)

兩階段提交(Two Phase Commit, 2PC), 具備強一致性, 是CP系統的一種典型實現.性能

兩階段提交, 常見的標準是XA, JTA等. 例如Oracle的數據庫支持XA.ui

下圖是兩階段提交的示意圖:spa

2pc

圖的上半是兩階段提交成功的演示, 下半是兩階段提交失敗的演示. 關於兩階段提交網上有不少經典的講解, 這裏就不細說了, 能夠參考前面的連接.

缺點

  • 兩階段提交中的第二階段, 協調者須要等待全部參與者發出yes請求, 或者一個參與者發出no請求後, 才能執行提交或者中斷操做. 這會形成長時間同時鎖住多個資源, 形成性能瓶頸, 若是參與者有一個耗時長的操做, 性能損耗會更明顯.
  • 實現複雜, 不利於系統的擴展, 不推薦.

3、補償性的TCC (Try-Confirm-Cancle)類型

TCC, 是基於補償型事務的AP系統的一種實現, 具備最終一致性.

TCC流程

下面以客戶購買商品時的付款操做爲例進行講解:

  • Try: 
    完成全部的業務檢查(一致性),預留必須業務資源(準隔離性); 
    體如今本例中, 就是確認客戶帳戶餘額足夠支付(一致性), 鎖住客戶帳戶, 商戶帳戶(準隔離性).
  • Confirm: 
    使用Try階段預留的業務資源執行業務(業務操做必須是冪等的), 若是執行出現異常, 要進行重試. 
    在這裏就是執行客戶帳戶扣款, 商戶帳戶入帳操做.
  • Cancle: 
    釋放Try階段預留的業務資源, 在這裏就是釋放客戶帳戶和商戶帳戶的鎖; 
    若是任一子業務在Confirm階段有操做沒法執行成功, 會形成對業務活動管理器的響應超時, 此時要對其餘業務執行補償性事務. 若是補償操做執行也出現異常, 必須進行重試, 若實在沒法執行成功, 則事務管理器必須可以感知到失敗的操做, 進行log(用於過後人工進行補償性事務操做或者交由中間件接管在以後進行補償性事務操做).

優勢

對比與前面提到的兩階段提交法, 有兩大優點:

  • TCC可以對分佈式事務中的各個資源進行分別鎖定, 分別提交與釋放, 例如, 假設有AB兩個操做, 假設A操做耗時短, 那麼A就能較快的完成自身的try-confirm-cancel流程, 釋放資源. 無需等待B操做. 若是過後出現問題, 追加執行補償性事務便可.
  • TCC是綁定在各個子業務上的(除了cancle中的全局回滾操做), 也就是各服務之間能夠在必定程度上」異步並行」執行.

注意事項

  • 事務管理器(協調器)這個節點必須以帶同步複製語義的高可用集羣(HAC)方式部署.
  • 事務管理器(協調器)還須要使用多數派算法來避免集羣發生腦裂問題.

適用場景

  • 嚴格一致性
  • 執行時間短
  • 實時性要求高

舉例: 紅包, 收付款業務.

4、異步確保型(消息事務+最終一致性)

經過將一系列同步的事務操做變爲基於消息執行的異步操做, 避免了分佈式事務中的同步阻塞操做的影響.

這個方案真正實現了兩個服務的解耦, 解耦的關鍵就是異步消息和補償性事務.

這裏以一個例子做爲講解:

異步確保型

執行步驟以下:

  1. MQ發送方發送遠程事務消息到MQ Server;
  2. MQ Server給予響應, 代表事務消息已成功到達MQ Server.
  3. MQ發送方Commit本地事務.
  4. 若本地事務Commit成功, 則通知MQ Server容許對應事務消息被消費; 若本地事務失敗, 則通知MQ Server對應事務消息應被丟棄.
  5. 若MQ發送方超時未對MQ Server做出本地事務執行狀態的反饋, 那麼須要MQ Servfer向MQ發送方主動回查事務狀態, 以決定事務消息是否能被消費.
  6. 當得知本地事務執行成功時, MQ Server容許MQ訂閱方消費本條事務消息.

須要額外說明的一點, 就是事務消息投遞到MQ訂閱方後, 並不必定可以成功執行. 須要MQ訂閱方主動給予消費反饋(ack)

  • 若是MQ訂閱方執行遠程事務成功, 則給予消費成功的ack, 那麼MQ Server能夠安全將事務消息移除;
  • 若是執行失敗, MQ Server須要對消息從新投遞, 直至消費成功.

注意事項

  • 消息中間件在系統中扮演一個重要的角色, 全部的事務消息都須要經過它來傳達, 因此消息中間件也須要支持 HAC 來確保事務消息不丟失.
  • 根據業務邏輯的具體實現不一樣,還可能須要對消息中間件增長消息不重複, 不亂序等其它要求.

適用場景

  • 執行週期較長
  • 實時性要求不高

例如:

  • 跨行轉帳/匯款業務(兩個服務分別在不一樣的銀行中)
  • 退貨/退款業務
  • 財務, 帳單統計業務(先發送到消息中間件, 而後進行批量記帳)

5、最大努力通知型

這是分佈式事務中要求最低的一種, 也能夠經過消息中間件實現, 與前面異步確保型操做不一樣的一點是, 在消息由MQ Server投遞到消費者以後, 容許在達到最大重試次數以後正常結束事務.

適用場景

交易結果消息的通知等.

小結

不論是同步事務中的事務管理器(協調者), 仍是異步事務中使用的消息中間件,若要達到一致性保證,都須要使用帶有同步複製語義的 HAC 提供的高可用和高可靠特性,這些都是以性能爲代價的,無疑成爲了SOA 架構中的典型性能瓶頸之一.

相關文章
相關標籤/搜索