開發與維運

分佈式柔性事務之事務消息詳解

  • 消息詳解 -

一、概述
在 《柔性事務之TCC詳解》 和《柔性事務之Saga詳解》兩文中我們詳細剖析了柔性事務的第一個分支補償型事務。在《剛性事務總結和柔性事務概述》中我們介紹過的柔性事務包含補償型事務和通知型事務。

通知型事務主要包含事務消息和最大努力通知型分佈式事務兩個組成。通知型事務的核心思想是通過MQ來通知其他事務參與者自己事務的執行狀態。MQ組件的引入有效的將事務參與者解耦開,各個參與者都可以異步執行,所以通知型事務又稱為異步事務。

事務消息的難度在於服務本地事務和投遞消息的一致性保障。目前業界解決這個一致性的方案有兩個分支:

基於MQ自身的事務消息方案
基於DB的本地消息表方案

  • 基於MQ自身的事務消息方案 -

基於MQ的事務消息方案主要依靠MQ的半消息機制來實現投遞消息和參與者自身本地事務的一致性保障。半消息機制實現原理其實借鑑的2PC的思路,是二階段提交的廣義拓展,流程圖如下:

attachments-2020-06-VfgahNdk5ef05c87a130a.png

1、事務發起方首先發送prepare消息到MQ;

2、在發送prepare消息成功後執行本地事務;

3、根據本地事務執行結果返回commit或者是rollback;

4、如果消息是rollback, MQ將刪除該prepare消息不進行下發,如果是commit消息,MQ將會消息發送給consumer端;

5、如果執行本地事務過程中,執行端掛掉,或者超時,MQ服務器端將不停的詢問producer來獲取事務狀態;

6、Consumer端的消費成功機制有MQ保證

MQ事務消息方案因為使用了半消息機制,對業務頁具有比較大侵入性,有以下注意點:

1、 業務方調用半消息,並提供對應的回查方法;

2、 MQ提要提供半消息機制,並定期掃描長期半消息,對消息生產者進行回查確認事務。

3、 消費方需要進行冪等消費。

  • 基於BD的本地消息表方案 -

有時候我們目前的MQ組件並不支持事務消息,或者我們想盡量少的侵入業務方。這時我們需要另外一種方案“基於DB本地消息表“,流程圖如下:

attachments-2020-06-I1HCABg25ef05ca527f47.png

1、 業務方:直接利用本地事務,將業務數據和事務消息直接寫入數據庫。

2、 投遞線程:使用專門的投遞工作線程進行事務消息投遞到MQ,根據投遞ACK去刪除事務消息表記錄

本地事務消息表的優勢在於方案的通用性,無需提供回查方法,進一步減少的業務的侵入。在某些場景下,還可以進一步利用註解等形式進行解耦,有可能實現無業務代碼侵入式的實現。我們上面說了本地事務消息表的基本理論,那麼如果要設計一個高可用的企業級本地事務消息表方案,就要考慮更多的事情,在性能上做更大的優化,降低更多的重複投遞率。以下是一個企業級事務消息的設計流程圖:

attachments-2020-06-3vH4McP95ef05cb24486c.png

1、 事務消息服務:提供通用投遞接口,用於保證事務消息的本地寫入,並將事務消息寫入事務內存隊列。

2、 使用投遞線程池,繼續事務內存隊列投遞派發分配。投遞工作線程只投遞本實例擁有的事務消息,投遞失敗線程列入時間輪隊列;重試機制使用失敗擋位區分,默認提供6檔:5s、10s、15s、20s、25s、30s。

3、 時間輪線程進行60秒轉動,將到期的失敗事務消息重入事務內存隊列.

4、 因為我們的事務消息服務是無狀態化的多實例存在,所以需要一個持鎖線程進行主節點競爭強鎖,處理一些額外的工作。

5、 因為我們的事務內存隊列是內存級,不可避免面臨重啟等情況下的數據丟失。這時需要事務消息服務主節點進行定期掃表,將長期未投遞的事務消息取出放入事務消息服務。

6、 事務消息服務主節點還有一個清理線程,專門用於將已處理成功的歷史事務消息進行歸檔清理,降低DB的數據量。

  • 總結 -

咱們上面介紹了MQ事務消息方案和DB本地消息表方案,這兩個方案有什麼區別呢?

1、 MQ事務消息方案

a) 需要MQ支持半消息機制或者類似特性,在重複投遞上具有比較好的去重處理

b) 需要業務方進行改造,提供對應的本地操作成功回查功能。具有比較大的業務侵入性。

2、 DB本地事務消息表方案

a) 使用了數據庫來存儲事務消息,降低了對MQ的需求,但是增加了存儲成本。

b) 事務消息使用了異步投遞,增大了消息重複投遞的可能性。

我們說了兩種事務消息的特性和優劣性,我們在總結下事務消息的共性。

1、 事務消息都依賴MQ進行事務通知,所以都是異步的。

2、 事務消息在投遞方都是存在重複投遞的可能,需要有配套的機制去降低重複投遞率,實現更友好的消息投遞去重。

3、 事務消息的消費方,因為投遞重複的無法避免,因此需要進行消費去重設計或者服務冪等設計。

本文來源於:奈學開發者社區  

如有侵權請聯繫我刪除。

Leave a Reply

Your email address will not be published. Required fields are marked *