微服務架構中分佈式事務解決方案總結

前言:最近,在家裏養傷,因爲博主騎自行車不當心摔跤了,給本身形成了影響,同時也給公司形成了影響,沒有按時報到。但願你們騎自行車時必定要當心,手裏不要拿手機,仍是那句話:道路千萬條,安全第一條,行車不規範,親人兩行淚。好了,這是血的教訓。今天的主題不是教如何騎自行車,哈哈哈。言歸正傳,利用在家養傷總結一下面試中常常問到的在微服務架構中如何解決分佈式事務的問題。由於,這個問題,當時回答的不是太好,下來也查詢不少資料,算是總結一下學習的心得,若是有不對的地方還請大佬們能多多指點。html

 

1、理論

首先這個問題是出如今微服務架構、分佈式環境中的,在單機系統中是不用考慮這個問題的,首先咱們來看下分佈式系統的CAP原則和BASE理論。面試

 

 

 咱們知道,這個三個特徵最多隻能知足兩個,三者不可兼得。一致性:全部節點在同一時間點全部的數據都是一致的。可用性:在任什麼時候候分佈式系統老是能夠成功讀和寫。分區容忍性:在某些節點由於網絡故障時,仍然可以知足一致性和可用性的服務。數據庫

選擇CA:放棄p 等同於放棄分佈式系統,只存在於單機系統
選擇CP:也就是選擇分區容忍性和強一致性,容許在極端狀況下出現暫時服務的不可用。
選擇AP:容許出現數據的短時不一致,在服務註冊的場景短時間的數據不一致,不會對服務形成影響。所以採用AP原則的註冊中心纔是微服務比較合適的選擇。安全

而後,介紹一下BASE理論,如圖底部的詞彙,BASE指Basically Available 基本可用,Soft-state 軟狀態(狀態容許有短期不一樣步,異步), Eventual Consistency 最終一致性,它是對CAP中一致性和可用性的權衡的結果,BASE的核心思想是即便沒法作到強一致性,也能夠根據系統特性,採用適當的方式達到最終一致性。基於這樣的理論知識,咱們只要作到最終一致性就能夠解決分佈式系統中的問題了。在分佈式系統中,最重要的是知足業務需求,而不是追求抽象、絕對的系統特性。網絡

若是感受仍是不太明白建議參考CAP框架做者的這篇文章:https://www.cnblogs.com/savorboard/p/base-an-acid-alternative.html架構

 

2、場景

一圖勝千言:框架

 

 

3、解決方案分析

解決方案:異步

(1)剛性事務分佈式

  全局事務(標準的分佈式事務)微服務

  優勢:嚴格的ACID;

  缺點:效率很是低(微服務架構下已經不太合適)

  緣由:1)全局事務方式下,全局事務管理器(TM)經過XA接口使用二階段提交協議(2pc)與資源層(如數據庫進行交互)。使用全局事務,數據被lock的時間跨整個事務,直到全局事務結束。

     2)2pc是反可伸縮模式,在事務處理過程當中,參與者須要一直持有資源直到整個分佈式事務結束,這樣當業務規模愈來愈大的狀況下,2pc的侷限性就愈來愈明顯,系統可伸縮性就會變的不好。

     3)與本地事務相比,XA協議的系統開銷至關大,於是應當謹慎考慮是否確實須要分佈式事務。並且只有支持XA協議的資源才能參與分佈式事務。

    

(2)柔性事務

  可靠消息最終一致性(異步確保型)

  

 

   

  TCC(兩階段型、補償型)【略】

  最大努力通知(非可靠消息、按期校對)【略】

 

咱們如今知道有這麼多解決分佈式事務的方案,咱們可否本身去實現一個分佈式事務框架呢?假如咱們選擇柔性事務中的,可靠消息最終一致(異步確保型)這種方案來實現就不得不涉及到消息中間件的使用了,消息中間價在分佈式系統中的主要做用是,異步通信、解耦、削峯填谷等。以下圖所示:

 

 若是按照上面的圖,你們可能認爲它很簡單呀,一個發送消息,一個接受消息。可是在分佈式系統中,須要經過網絡進行通訊的,就引入了數據傳輸的不肯定性,也就是CAP理論中的P(分區容錯性的問題),以下圖所示:

 

 很顯然,正是由於跨網絡,就會產生消息發送不一致的問題,也就是說,若是個人業務操做成功,那麼有這個業務操做所產生的消息必定要成功投遞出去,不然就丟失消息。那麼咱們該怎麼解決這樣的問題呢?

也就是如何保障消息發送一致性?一般咱們在使用消息隊列來處理業務都會遇到這樣的場景:

public  void CompleteOrder() { //訂單處理
 orderService.OrderProcess(); //財務處理(發送消息) 
 ...... }

 

(1)若是業務操做成功,執行消息發送前應用故障,消息發送不去去,致使消息丟失(訂單系統和財務系統數據產生不一致)

(2)若是業務操做成功,應用正常,但消息系統故障或者網絡故障,也會致使消息發送不出去(訂單系統和財務系統數據產生不一致)。

另一種處理方案:

public  void CompleteOrder() { //財務處理(發送消息) 
 ...... //訂單處理
 orderService.OrderProcess(); }

 

也就是,我先發送消息再處理訂單,這種作法更不可控了,消息發送出去了,可是訂單處理失敗了(致使訂單和財務系統數據的不一致),記住在處理這種場景,必定是業務數據先入庫,再發送消息的。

貌似這兩種方式都不能保證業務數據的一致性,固然,咱們能夠藉助JMS標準中的XA協議方式來保證消息發送的一致性,可是這種方式引入了XA,違背了柔性事務的初衷,會帶來不少侷限性:

(1)要求業務操做的資源(也就是數據庫)必須支持XA協議(並非全部的數據庫都支持XA)

(2)兩階段提交協議的成本

(3)持久化成本等DTP模型的侷限性(全局鎖、成本高、性能低)

另一種變通的作法以下:(這種方案只是解決的業務處理成功,消息必定能發送到消息中間件中)

 

 問題:

(1)上面的消息發送一致性方案的正向流程是可行的,可是若是遇到異常流程該怎麼處理?

(2)消息發送到消息中間件能獲得保障,可是消息的準確消費又如何保障呢?

(3)有沒有支持這種發送一致性流程的現成消息中間件?

 先來聊聊問題(1),有哪些場景會出現異常,以下圖所示:

 

 從主動應用方(生產者)來分析:

(1)預發消息失敗,消息未進行存儲,業務操做未執行(可能的緣由:主動方應用、網絡、消息中間件、消息存儲等),這種場景不會出現不一致性。

(2)預發送消息後,主動方應用沒有收到返回消息存儲結果,可能的狀態有:消息未進行存儲,業務操做未執行(不會出現不一致性);若是消息已進行存儲【待確認】,業務操做未執行,會出現不一致性。

(3)收到消息存儲成功的返回結果,但未執行業務操做就失敗,可能的狀態有:消息已進行存儲【待確認】,業務操做未執行,會出現不一致性的問題。

 從消息中間件的角度分析:

(1)消息中間件沒有收到主動方應用的業務操做處理結果,可能的狀態:消息已經存儲(待確認),業務操做未執行(或者業務操做出錯回滾了),會出現數據的不一致性問題;若是消息已經存儲(待確認),業務操做成功,也會出現數據的不一致性。

(2)消息中間件收到業務操做結果(成功/失敗),但處理消息存儲中的消息狀態失敗,可能的狀態:消息已經存儲(待確認),業務操做未執行(或業務操做出錯回滾了),會出現數據的不一致性問題;若是消息已經存儲(待確認),業務操做成功,也會出現數據的不一致性問題。

 

那咱們該如何處理這樣的異常問題呢?以下圖所示:

 

 這樣就能夠處理異常的流程,有人可能會說,異常處理流程也可能發生異常呀,其實你們認真看的話,異常處理基本上都是查詢,若是查詢出現了異常,定時補救也是能夠的。

總結:關於上面異常處理總結

(1)消息未進存儲,業務操做未執行,不會出現一致性問題。

(2)消息已進行存儲(待確認),業務操做未執行,會出現一致性問題,異常處理手段,確認業務操做結果,處理消息【刪除消息】

(3)消息已進行存儲(待確認),業務操做成功,會出現一致性問題,異常處理手段,確認業務操做結果,處理消息【更新消息狀態,執行消息投遞】

 

對於問題(3)有沒有現成的消息中間件支持消息發送一致性,答案是:沒有。是由於經常使用的MQ隊列消息的處理流程沒法實現消息發送一致性,所以直接使用現成的MQ中間件產品沒法實現可靠消息最終一致性的分佈式解決方案。

對於問題(2)消息發送到消息中間件能獲得保障,可是消息的準確消費又如何保障呢?

之前的流程,以下圖所示:

 

 紅框圈住的就是消息的消費流程,在這個流程中,任何一個環節都有可能出問題具體到下面這張圖:

 

 那咱們如何處理,這些異常呢?處理的方法有不少,這裏列出常規的作法:對於未確認的消息,採用按照規則從新投遞的方式進行處理。這裏就不介紹了,  固然,咱們須要處理極端狀況:消息重發也得有次數限制,要否則就變成了死循環,對於超太重發次數的消息,進入到死信隊列,等待人工干預或者延後按期處理。同時也須要處理被動方在處理業務時要實現冪等操做。

 

4、總結

好了,暫時分享到這裏吧,雖然在分佈式系統中已經有現成的框架,好比.net core 中的 CAP框架,很是的不錯,咱們生產環境中已經用了很長時間,框架能幫助咱們解決實際場景下的問題,可是咱們也要明白框架背後的原理,明白大概的原理,再去看CAP的源碼,你會恍然大悟的!哈哈哈哈。

 

 

 

 

參考資料:

 

龍果學院   吳水成老師   《微服務架構的分佈式事務解決方案》  https://www.roncoo.com/details/7ae3d7eddc4742f78b0548aa8bd9ccdb

CAP框架做者  楊老師   https://www.cnblogs.com/savorboard/p/base-an-acid-alternative.html

 

 

 

 

做者:郭崢

出處:http://www.cnblogs.com/runningsmallguo/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

相關文章
相關標籤/搜索