1. 程式人生 > >分散式事務之最終一致的Mq實現

分散式事務之最終一致的Mq實現

問題的起源

分散式系統的特性

對分散式系統有過研究的讀者,可能聽說過“CAP定律”、“Base理論”等,非常巧的是,化學理論中ACID是酸、Base恰好是鹼。這裡我們不對這些概念做過多的解釋,有興趣的讀者可以檢視相關參考資料。

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

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

強一致

當更新操作完成之後,任何多個後續程序或者執行緒的訪問都會返回最新的更新過的值。這種是對使用者最友好的,就是使用者上一次寫什麼,下一次就保證能讀到什麼。根據 CAP 理論,這種實現需要犧牲可用性。

弱一致

系統並不保證續程序或者執行緒的訪問都會返回最新的更新過的值。系統在資料寫入成功之後,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之後可以讀到。

最終一致

弱一致性的特定形式。系統保證在沒有後續更新的前提下,系統最終返回上一次更新操作的值。在沒有故障發生的前提下,不一致視窗的時間主要受通訊延遲,系統負載和複製副本的個數影響。DNS 是一個典型的最終一致性系統。

在分散式系統中,同時滿足“CAP定律”中的“一致性”、“可用性”和“分割槽容錯性”三者是幾乎不可能的。在網際網路領域的絕大多數的場景,都需要犧牲強一致性來換取系統的高可用性,系統往往只需要保證“最終一致性”,只要這個最終時間是在使用者可以接受的範圍內即可,這時候我們只需要用短暫的資料不一致就可以達到我們想要效果。

例項描述

比如有訂單,庫存兩個資料,一個下單過程簡化為,加一個訂單,減一個庫存。 而訂單和庫存是獨立的服務,那怎麼保證資料一致性。

這時候我們需要思考一下,怎麼保證兩個遠端呼叫“同時成功”,資料一致?

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

一般的解決方案,大多數的做法是藉助mq來做最終一致。

如何實現最終一致

例項分析

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

訂單業務分析

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

在我們進行加訂單的過程中同時插入logA(這個過程是可以做本地事務的)
然後可以非同步讀取logA,發mqA
B端接收mqA,同時減少庫存,B這裡需要做冪等(避免因為重複訊息造成的業務錯亂)

複雜的混合非同步業務呼叫

那麼我們通過上面的分析可能聯想到這樣的問題?

本地先執行事務,執行成功了就發個訊息過去,消費端拿到訊息執行自己的事務。
比如a,b,c a非同步呼叫b,c, 如果b失敗了,或者b成功,或者b超時,那麼怎麼用mq讓他們最終一致呢?b失敗就失敗了,b成功之後給c發一個訊息,b和c對a來講都是非同步的,且他們都是同時進行的話,而且需要a,b,c同時成功的情況,那麼這種情況用mq怎麼做?
其實做法還是參照於本地事務的概念的。

第一種情況:假設a,b,c三者都正常執行,那整個業務正常結束

第二種情況:假設b超時,那麼需要a給b重發訊息(記得b服務要做冪等),如果出現重發失敗的話,需要看情況,是終端服務,還是繼續重發,甚至人為干預(所有的規則制定都需要根據業務規則來定)

第三種情況:假設a,b,c三者之中的一個失敗了,失敗的服務利用MQ給其他的服務傳送訊息,其他的服務接收訊息,查詢本地事務記錄日誌,如果本地也失敗,刪除收到的訊息(表示訊息消費成功),如果本地成功的話,則需要呼叫補償介面進行補償(需要每個服務都提供業務補償介面)。

注意事項

mq這裡有個坑,通常只適用於只允許第一個操作失敗的場景,也就是第一個成功之後必須保證後面的操作在業務上沒障礙,不然後面失敗了前面不好回滾,只允許系統異常的失敗,不允許業務上的失敗,通常業務上失敗一次後面基本上也不太可能成功了,要是因為網路或宕機引起的失敗可以通過重試解決,如果業務異常,那就只能發訊息給a和c讓他們做補償了吧?通常是通過第三方進行補償,ABC提供補償介面,設計正規化裡通常不允許消費下游業務失敗

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

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

阿里在分散式事務採用的解決方式

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

文/jsondream(簡書作者)

相關推薦

分散式事務最終一致Mq實現

問題的起源 分散式系統的特性 對分散式系統有過研究的讀者,可能聽說過“CAP定律”、“Base理論”等,非常巧的是,化學理論中ACID是酸、Base恰好是鹼。這裡我們不對這些概念做過多的解釋,有興趣的讀者可以檢視相關參考資料。 這裡針對一致性我

分散式事務MQ可靠訊息

使用MQ可靠訊息能夠解決分散式事務的最終一致性,但不是實時一致(強一致性)。所以使用時要注意應用場景。 MQ可靠訊息: 1.預發訊息:MQ傳送訊息之前把訊息的資訊先存到資料庫中留底,設定一個欄位狀態為待確認。(作用:能夠知道這條訊息是否傳送成功,可進行人工補償) 2.進行業務操作 3

【轉】分散式事務TCC服務設計和實現注意事項

1、TCC簡介 TCC是一種比較成熟的分散式事務解決方案,可用於解決跨庫操作的資料一致性問題; TCC是服務化的兩階段程式設計模型,其Try、Confirm、Cancel 3個方法均由業務編碼實現; 其中Try操作作為一階段,負責資源的檢查和預留,Confirm操作作為二階段提交操作,執行真正的業務,C

分散式事務——基於訊息中介軟體實現

 環境需求:假如某人有5個女朋友(有點複雜),每天晚上都會給他的女朋友打電話說晚安,那麼每給一個女朋友打電話,其他女朋友都要進入等待狀態。一個一個打下去。。。等打到最後一個已經是凌晨了,對方都睡了。那麼有什麼辦法可以解決呢?此時這個人可以利用微信公眾號將自己甜言蜜語放進公眾號

分散式sessionredis解決方案實現

  一、首先Session   Session 是客戶端與伺服器通訊會話技術, 比如瀏覽器登陸、記錄整個瀏覽會話資訊。session存放在伺服器,關閉瀏覽器不會失效。 Session實現原理 客戶對向伺服器端傳送請求後,Session 建立在伺服器端,返回Sessionid給客戶

分散式事務——tcc-transaction分散式TCC型事務框架搭建與實戰案例【轉】

一、背景 有一定分散式開發經驗的朋友都知道,產品/專案/系統最初為了能夠快速迭代上線,往往不太注重產品/專案/系統的高可靠性、高效能與高擴充套件性,採用單體應用和單例項資料庫的架構方式快速迭代開發;當產品/專案/系統做到一定規模的時候,原有的系統架構則不足以支撐義務發展需要,往往相同的業務則需要

分散式redis鎖及實現

分散式鎖有幾種常用的實現方式:zookeeper、memcached、redis、mysql。這裡介紹一下redis的實現方式,並在最後附上了一個Demo小工具: 眾所周知,reids鎖是通過setnx + expire的方式實現的,setnx保證只有在key不存在時才能se

分散式事務本地訊息表

什麼是分散式事務 分散式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分散式系統的不同節點之上。簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的伺服器上,且屬於不同的應用,分散式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分散式事務就

分散式事務可靠訊息

什麼是可靠訊息? 為什麼我們需要它,為什麼我們要強調可靠? 生產方 訊息傳送出去了,如果生產方收到了訊息的正常反饋,那麼我們就可以知道訊息的確切的狀態。 如果訊息無響應 或者超時了呢? 有多個情況, 1 訊息未到達mq,傳送途中 就某些原因丟失了, 2 訊息送達mq,但是mq處理未完成就丟失(這裡又可

分散式事務——MySQL對XA事務的支援

 MySQL 從5.0.3開始支援XA分散式事務,且只有InnoDB儲存引擎支援。MySQL Connector/J 從5.0.0版本之後開始直接提供對XA的支援。 需要注意的是, 在DTP模型中,mysql屬於資源管理器(RM)。而一個完整的分散式事務中,一般會存在多個RM

分散式事務TCC

TCC本質上也是一種二階段協議,不同在於TCC需要與具體業務耦合,下面首先看下TCC步驟: 所有事務參與方都需要實現try,confirm,cancle介面。 事務發起方向事務協調器發起事務請求,事務協調器呼叫所有事務參與者的try方法完成資源的預留,這時候

跟我學分散式事務2PC和3PC

分散式一致性回顧 在分散式系統中,為了保證資料的高可用,通常,我們會將資料保留多個副本(replica),這些副本會放置在不同的物理的機器上。為了對使用者提供正確的增\刪\改\差等語義,我們需要保證這些放置在不同物理機器上的副本是一致的。 為了解決這種分散式一致性問題

分散式事務TCC與XA

TCC與XA/JTA對比 XA是資源層面的分散式事務,強一致性,在兩階段提交的整個過程中,一直會持有資源的鎖。基於資料庫鎖實現。 TCC是業務層面的分散式事務,最終一致性,不會一直持有資源的鎖。(第

分散式事務方案 - 最終一致性

在分散式時代,分庫分表是很常見的,微服務系統中,各個系統通常使用獨立的資料庫,所以,事務很難靠資料庫本身保證,只能靠業務系統來解決。 例如支付寶中的餘額寶、花唄,具體不清楚,但猜測應該就是2個服務,不是同一個資料庫,我們還花唄的時候通常都是從餘額寶中扣除的,這就是分散式事務,一個系統中扣減錢,一個系統中增加錢

Spring Cloud Alibaba | 微服務分散式事務Seata

Spring Cloud Alibaba | 微服務分散式事務之Seata 本篇實戰所使用Spring有關版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Greenwich.SR2 Spring CLoud Alibaba:2.1.0.RELEASE 1. 概述 在構建

微服務分散式事務LCN、TCC

在[億級流量架構之分散式事務解決方案對比](https://www.cnblogs.com/Courage129/p/14443653.html)中, 已經簡單闡明瞭從本機事務到分散式事務的演變過程, 文章的最後簡單說明了TCC事務, 這兒將會深入瞭解TCC事務是原理, 以及理論支援, 最後會用Demo舉例實

曹工雜談:分散式事務解決方案基於本地訊息表實現最終一致性

# 曹工雜談:分散式事務解決方案之基於本地訊息表實現最終一致性 # 前言 為什麼寫這個?其實我這邊的業務場景,嚴格來說,不算是典型的分散式事務,需求是這樣說的:因為我這邊負責的一個服務消費者consumer,是使用者登入的入口;正常情況下,登入時候要走使用者中心,這是個單獨的服務;如果使用者中心掛了,我這

關於利用MQ實現分散式事務的想法【轉】

轉自:https://www.jianshu.com/p/bafb09954f18   假設:訊息服務不丟訊息 場景 服務A 服務B 服務C 訊息服務Q 虛擬碼 服務A中 transaction{ A本地事務 B.callB(); C.callC(); A本地事務

如何選擇分散式事務形態(TCC、SAGA、補償、基於訊息的最終一致等等)

各種形態的分散式事務 分散式事務有多種主流形態,包括: 基於訊息實現的分散式事務 基於補償實現的分散式事務 基於TCC實現的分散式事務 基於SAGA實現的分散式事務 基於2PC實現的分散式事務 這些形態的原理已經在很多文章中進行了剖析,用“分

mq實現dubbo分散式事務

1.本地事務 我們通常只需藉助開發平臺中特有資料訪問技術和框架(例如Spring、JDBC、ADO.NET),結合關係型資料庫自帶的事務管理機制來實現事務性的需求。例如A給B轉賬100元併發送100代金券,不管是伺服器掛掉還是轉賬失敗丟擲異常,我們最終都要保證這