分布式事務之最終一致的Mq實現(xiàn)

問題的起源

分布式系統(tǒng)的特性

對分布式系統(tǒng)有過研究的讀者,可能聽說過“CAP定律”、“Base理論”等,非常巧的是,化學理論中ACID是酸、Base恰好是堿。這里我們不對這些概念做過多的解釋,有興趣的讀者可以查看相關參考資料。

這里針對一致性我們做個簡單的科普:

分布式事務有強一致,弱一致,和最終一致性這三種:

強一致

當更新操作完成之后,任何多個后續(xù)進程或者線程的訪問都會返回最新的更新過的值。這種是對用戶最友好的,就是用戶上一次寫什么,下一次就保證能讀到什么。根據(jù) CAP 理論,這種實現(xiàn)需要犧牲可用性。

弱一致

系統(tǒng)并不保證續(xù)進程或者線程的訪問都會返回最新的更新過的值。系統(tǒng)在數(shù)據(jù)寫入成功之后,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之后可以讀到。

最終一致

弱一致性的特定形式。系統(tǒng)保證在沒有后續(xù)更新的前提下,系統(tǒng)最終返回上一次更新操作的值。在沒有故障發(fā)生的前提下,不一致窗口的時間主要受通信延遲,系統(tǒng)負載和復制副本的個數(shù)影響。DNS 是一個典型的最終一致性系統(tǒng)

在分布式系統(tǒng)中,同時滿足“CAP定律”中的“一致性”、“可用性”和“分區(qū)容錯性”三者是幾乎不可能的。在互聯(lián)網領域的絕大多數(shù)的場景,都需要犧牲強一致性來換取系統(tǒng)的高可用性,系統(tǒng)往往只需要保證“最終一致性”,只要這個最終時間是在用戶可以接受的范圍內即可,這時候我們只需要用短暫的數(shù)據(jù)不一致就可以達到我們想要效果。

實例描述

比如有訂單,庫存兩個數(shù)據(jù),一個下單過程簡化為,加一個訂單,減一個庫存。 而訂單和庫存是獨立的服務,那怎么保證數(shù)據(jù)一致性。

這時候我們需要思考一下,怎么保證兩個遠程調用“同時成功”,數(shù)據(jù)一致?

請大家先注意一點遠程調用最郁悶的地方就是,結果有3種,成功、失敗和超時。 超時的話,成功失敗都有可能。

一般的解決方案,大多數(shù)的做法是借助mq來做最終一致。

如何實現(xiàn)最終一致

實例分析

我們是怎么利用Mq來達到最終一致的呢?下面讓我們來一起進行詳細的分析:

訂單業(yè)務分析

首先,拿我們上面提到的訂單業(yè)務舉例:

  • 在我們進行加訂單的過程中同時插入logA(這個過程是可以做本地事務的)
  • 然后可以異步讀取logA,發(fā)mqA
  • B端接收mqA,同時減少庫存,B這里需要做冪等(避免因為重復消息造成的業(yè)務錯亂)

復雜的混合異步業(yè)務調用

那么我們通過上面的分析可能聯(lián)想到這樣的問題?

本地先執(zhí)行事務,執(zhí)行成功了就發(fā)個消息過去,消費端拿到消息執(zhí)行自己的事務
比如a,b,c a異步調用b,c, 如果b失敗了,或者b成功,或者b超時,那么怎么用mq讓他們最終一致呢?b失敗就失敗了,b成功之后給c發(fā)一個消息,b和c對a來講都是異步的,且他們都是同時進行的話,而且需要a,b,c同時成功的情況,那么這種情況用mq怎么做

其實做法還是參照于本地事務的概念的。

  • 第一種情況:假設a,b,c三者都正常執(zhí)行,那整個業(yè)務正常結束
  • 第二種情況:假設b超時,那么需要a給b重發(fā)消息(記得b服務要做冪等),如果出現(xiàn)重發(fā)失敗的話,需要看情況,是終端服務,還是繼續(xù)重發(fā),甚至人為干預(所有的規(guī)則制定都需要根據(jù)業(yè)務規(guī)則來定)
  • 第三種情況:假設a,b,c三者之中的一個失敗了,失敗的服務利用MQ給其他的服務發(fā)送消息,其他的服務接收消息,查詢本地事務記錄日志,如果本地也失敗,刪除收到的消息(表示消息消費成功),如果本地成功的話,則需要調用補償接口進行補償(需要每個服務都提供業(yè)務補償接口)。

注意事項

mq這里有個坑,通常只適用于只允許第一個操作失敗的場景,也就是第一個成功之后必須保證后面的操作在業(yè)務上沒障礙,不然后面失敗了前面不好回滾,只允許系統(tǒng)異常的失敗,不允許業(yè)務上的失敗,通常業(yè)務上失敗一次后面基本上也不太可能成功了,要是因為網絡或宕機引起的失敗可以通過重試解決,如果業(yè)務異常,那就只能發(fā)消息給a和c讓他們做補償了吧?通常是通過第三方進行補償,ABC提供補償接口,設計范式里通常不允許消費下游業(yè)務失敗

上面的話我們該怎么理解呢,舉個例子吧

比如A給B轉賬,A先自己扣錢,然后發(fā)了個消息,B這邊如果在這之前銷戶了,那重試多少次也沒用,只能人工干預

阿里在分布式事務采用的解決方式

阿里部分業(yè)務是用Mq實現(xiàn)了最終一致性,也有一部分業(yè)務用了tcc事務,但是tcc事務用的比較少,因為會侵染業(yè)務,開發(fā)成本比較高,如果體量不大的話直接用jta或mq支持事務就好,其實在分布式事務這一塊還有一種最大努力型,也比較無腦的一種方式。

聲明

以上觀點均為個人總結,不代表完全正確。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容