溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

發(fā)布時間:2021-12-06 09:21:25 來源:億速云 閱讀:595 作者:柒染 欄目:大數(shù)據(jù)

這篇文章將為大家詳細講解有關(guān)寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

一、引子

隨著公司業(yè)務(wù)的增長,單體應(yīng)用架構(gòu)很難滿足業(yè)務(wù)快速迭代以及性能方面的需求,都會進行服務(wù)化改造,按照業(yè)務(wù)等要素將原來龐大的單體應(yīng)用拆分成不同的服務(wù)。那么在進行服務(wù)化改造之前首先就是面臨是服務(wù)化基礎(chǔ)設(shè)施的技術(shù)選型,其中最重要的就是服務(wù)之間的通信中間件。服務(wù)之間的通信可以分為同步方式和異步方式。同步的方式的代表就是 RPC,異步方式一般會選用mq。

二、問題的現(xiàn)實意義

如果我們要在服務(wù)化拆分中使用消息隊列,那么我們需要解決哪些問題呢?首先去哪兒網(wǎng)提供了旅游產(chǎn)品在線預(yù)訂服務(wù),那么就涉及電商交易,在電商交易中我們認為數(shù)據(jù)的一致性是非常關(guān)鍵的要素。那么我們的 MQ 必須提供一致性保證。

MQ 提供一致性保證又分為兩個方面。發(fā)消息時我們?nèi)绾未_保業(yè)務(wù)操作和發(fā)消息是一致的,也就是不能出現(xiàn)業(yè)務(wù)操作成功消息未發(fā)出或者消息發(fā)出了但是業(yè)務(wù)并沒有成功的情況。舉例來說,支付服務(wù)使用消息通知出票服務(wù),那么不能出現(xiàn)支付成功,但是消息沒有發(fā)出,這會引起用戶投訴;但是也不能出現(xiàn)支付未成功,但是消息發(fā)出最后出票了,這會導(dǎo)致公司損失??偨Y(jié)一下就是發(fā)消息和業(yè)務(wù)需要有事務(wù)保證。一致性的另一端是消費者,比如消費者臨時出錯或網(wǎng)絡(luò)故障,我們?nèi)绾未_保消息最終被處理了。那么我們通過消費 ACK 和重試來達到最終一致性。

三、利用數(shù)據(jù)庫事務(wù)解決一致性問題

提到一致性,大家肯定就想到事務(wù),而一提到事務(wù),肯定就想到關(guān)系型數(shù)據(jù)庫,那么我們是不是可以借助關(guān)系型 DB 里久經(jīng)考驗的事務(wù)來實現(xiàn)這個一致性呢。我們以 MySQL 為例,對于 MySQL 中同一個實例里面的 db,如果共享相同的 Connection 的話是可以在同一個事務(wù)里的。以下圖為例,我們有一個 MySQL 實例監(jiān)聽在 3306 端口上,然后該實例上有 A,B 兩個 DB,那么下面的偽代碼是可以跑在同一個事務(wù)里的

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

有了這層保證,我們就可以透明的實現(xiàn)業(yè)務(wù)操作和消息發(fā)送在同一個事務(wù)里了,首先我們在公司所有 MySQL 實例里初始化出一個 message db,這個可以放到自動化流程中(據(jù)說在去哪兒由運維團隊完成),對應(yīng)用透明。然后我們只要將發(fā)消息與業(yè)務(wù)操作放到同一個 DB 事務(wù)里即可。

我們來看一個實際的場景,在支付場景中,支付成功后我們需要插入一條支付流水,并且發(fā)送一條支付完成的消息通知其他系統(tǒng)。那么這里插入支付流水和發(fā)送消息就需要是一致的,任何一步?jīng)]有成功最后都會導(dǎo)致問題。那么就有下面的代碼

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

上面的代碼可以用下面的偽代碼解釋

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

實際上在 producer.sendMessage 執(zhí)行的時候,消息并沒有通過網(wǎng)絡(luò)發(fā)送出去,而僅僅是往業(yè)務(wù) DB 同一個實例上的消息庫插入一條記錄,然后注冊事務(wù)的回調(diào),在這個事務(wù)真正提交后消息才從網(wǎng)絡(luò)發(fā)送出去,這個時候如果發(fā)送到 server 成功的話消息會被立即刪除掉。而如果消息發(fā)送失敗則消息就留在消息庫里,這個時候我們會有一個補償任務(wù)會將這些消息從消息庫里撈出然后重新發(fā)送,直到發(fā)送成功。整個流程就如下圖所示

寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法

1、begin tx 開啟本地事務(wù)

2、do work 執(zhí)行業(yè)務(wù)操作

3、insert message 向同實例消息庫插入消息

4、end tx 事務(wù)提交

5、send message 網(wǎng)絡(luò)向 server 發(fā)送消息

6、reponse server 回應(yīng)消息

7、delete message 如果 server 回復(fù)成功則刪除消息

8、scan messages 補償任務(wù)掃描未發(fā)送消息

9、send message 補償任務(wù)補償消息

10、delete messages 補償任務(wù)刪除補償成功的消息 

關(guān)于寫數(shù)據(jù)庫同時發(fā)mq消息事務(wù)一致性的解決方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI