分散式事務(3)—RocketMQ實現分散式事務原理
之前講過有關分散式事務2PC、3PC、TCC的理論知識,部落格地址:
這篇講有關RocketMQ實現分散式事務的理論知識,下篇也會示例 通過SpringCloud來例項RocketMQ實現分散式事務的專案。
一、舉個分散式事務場景
列子
:假設 A 給 B 轉 100塊錢,同時它們不是同一個服務上。
目標
:就是 A 減100塊錢,B 加100塊錢。
實際情況可能有四種:
1)就是A賬戶減100 (成功),B賬戶加100 (成功)
2)就是A賬戶減100(失敗),B賬戶加100 (失敗)
3)就是A賬戶減100(成功),B賬戶加100 (失敗)
4)就是A賬戶減100 (失敗),B賬戶加100 (成功)
這裡 第1和第2 種情況是能夠保證事務的一致性的,但是 第3和第4 是無法保證事務的一致性的。
那我們來看下RocketMQ是如何來保證事務的一致性的。
二、RocketMQ實現分散式事務原理
RocketMQ雖然之前也支援分散式事務,但並沒有開源,等到RocketMQ 4.3才正式開源。
1、基礎概念
最終一致性
RocketMQ是一種最終一致性的分散式事務,就是說它保證的是訊息最終一致性,而不是像2PC、3PC、TCC那樣強一致分散式事務,至於為什麼說它是最終一致性事務下面會詳細說明。
Half Message(半訊息)
是指暫不能被Consumer消費的訊息。Producer 已經把訊息成功傳送到了 Broker 端,但此訊息被標記為暫不能投遞
狀態,處於該種狀態下的訊息稱為半訊息。需要 Producer
對訊息的二次確認
後,Consumer才能去消費它。
訊息回查
由於網路閃段,生產者應用重啟等原因。導致 Producer 端一直沒有對 Half Message(半訊息) 進行 二次確認。這是Brock伺服器會定時掃描長期處於半訊息的訊息
,會
主動詢問 Producer端 該訊息的最終狀態(Commit或者Rollback),該訊息即為 訊息回查。
2、分散式事務互動流程
理解這張阿里官方的圖,就能理解RocketMQ分散式事務的原理了。
我們來說明下上面這張圖
1、A服務先傳送個Half Message給Brock端,訊息中攜帶 B服務 即將要+100元的資訊。
2、當A服務知道Half Message傳送成功後,那麼開始第3步執行本地事務。
3、執行本地事務(會有三種情況1、執行成功。2、執行失敗。3、網路等原因導致沒有響應)
4.1)、如果本地事務成功,那麼Product像Brock伺服器傳送Commit,這樣B服務就可以消費該message。
4.2)、如果本地事務失敗,那麼Product像Brock伺服器傳送Rollback,那麼就會直接刪除上面這條半訊息。
4.3)、如果因為網路等原因遲遲沒有返回失敗還是成功,那麼會執行RocketMQ的回撥介面,來進行事務的回查。
從上面流程可以得知 只有A服務本地事務執行成功 ,B服務才能消費該message
。
然後我們再來思考幾個問題?
為什麼要先傳送Half Message(半訊息)
我覺得主要有兩點
1)可以先確認 Brock伺服器是否正常 ,如果半訊息都傳送失敗了 那說明Brock掛了。
2)可以通過半訊息來回查事務,如果半訊息傳送成功後一直沒有被二次確認,那麼就會回查事務狀態。
什麼情況會回查
也會有兩種情況
1)執行本地事務的時候,由於突然網路等原因一直沒有返回執行事務的結果(commit或者rollback)導致最終返回UNKNOW,那麼就會回查。
2) 本地事務執行成功後,返回Commit進行訊息二次確認的時候的服務掛了,在重啟服務那麼這個時候在brock端
它還是個Half Message(半訊息),這也會回查。
特別注意: 如果回查,那麼一定要先檢視當前事務的執行情況,再看是否需要重新執行本地事務。
想象下如果出現第二種情況而引起的回查,如果不先檢視當前事務的執行情況,而是直接執行事務,那麼就相當於成功執行了兩個本地事務。
為什麼說MQ是最終一致性事務
通過上面這幅圖,我們可以看出,在上面舉例事務不一致的兩種情況中,永遠不會發生
A賬戶減100 (失敗),B賬戶加100 (成功)
因為:如果A服務本地事務都失敗了,那B服務永遠不會執行任何操作,因為訊息壓根就不會傳到B服務。
那麼 A賬戶減100 (成功),B賬戶加100 (失敗) 會不會可能存在的。
答案是會的
因為A服務只負責當我訊息執行成功了,保證訊息能夠送達到B,至於B服務接到訊息後最終執行結果A並不管。
那B服務失敗怎麼辦?
如果B最終執行失敗,幾乎可以斷定就是程式碼有問題所以才引起的異常,因為消費端RocketMQ有重試機制,如果不是程式碼問題一般重試幾次就能成功。
如果是程式碼的原因引起多次重試失敗後,也沒有關係,將該異常記錄下來,由人工處理
,人工兜底處理後,就可以讓事務達到最終的一致性。
只要自己變優秀了,其他的事情才會跟著好起來(上將7)