自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

談?wù)勀銓?duì)RocketMQ分布式事務(wù)原理的理解

開(kāi)發(fā) 架構(gòu)
隨著應(yīng)用的拆分,從單體架構(gòu)變成分布式架構(gòu),那么每個(gè)服務(wù)或者模塊也會(huì)有自己的數(shù)據(jù)庫(kù)。一個(gè)業(yè)務(wù)流程的完成需要經(jīng)過(guò)多次的接口調(diào)用或者多條MQ消息的發(fā)送。

?有位工作五年的小伙伴在面試的時(shí)候被問(wèn)到RocketMQ的分布式事務(wù)實(shí)現(xiàn)原理。他說(shuō)他只知道RocketMQ能夠支持事務(wù),但是沒(méi)有了解過(guò)它的事務(wù)實(shí)現(xiàn)原理。

今天,我給大家分享一下我對(duì)這個(gè)問(wèn)題的理解。

1.分布式事務(wù)應(yīng)用場(chǎng)景

隨著應(yīng)用的拆分,從單體架構(gòu)變成分布式架構(gòu),那么每個(gè)服務(wù)或者模塊也會(huì)有自己的數(shù)據(jù)庫(kù)。一個(gè)業(yè)務(wù)流程的完成需要經(jīng)過(guò)多次的接口調(diào)用或者多條MQ消息的發(fā)送。

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

那么問(wèn)題來(lái)了,如果是執(zhí)行多條SQL語(yǔ)句,數(shù)據(jù)庫(kù)的本地事務(wù)可以保證原子性。

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

但,如果是一條SQL操作,再加一條MQ的操作,如何才能把它們兩個(gè)放在同一個(gè)邏輯單元里面執(zhí)行呢?是先執(zhí)行SQL還是先發(fā)送MQ呢?

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

我們來(lái)分析一下情況,如果是先發(fā)送MQ消息,再執(zhí)行SQL。這個(gè)時(shí)候就要分為兩種情況:

第1種情況:如果發(fā)送MQ失敗了,當(dāng)然SQL也就不會(huì)執(zhí)行了。

第2種情況:如果發(fā)送MQ成功了,而本地?cái)?shù)據(jù)庫(kù)SQL執(zhí)行失敗。比如出現(xiàn)了網(wǎng)絡(luò)異常,主鍵重復(fù)或者字段超長(zhǎng)等等。

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

也就是說(shuō),下游的業(yè)務(wù)系統(tǒng)拿到了最新的數(shù)據(jù),而自己本地的數(shù)據(jù)庫(kù)反而沒(méi)有。這個(gè)時(shí)候,本地?cái)?shù)據(jù)庫(kù)的數(shù)據(jù)跟其他系統(tǒng)已經(jīng)登記的數(shù)據(jù)就不一樣了,而發(fā)出去的消息又不可能撤回,有可能已經(jīng)被消費(fèi)了,這個(gè)叫做覆水難收。

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

因此,在分布式應(yīng)用場(chǎng)景中,我們需要調(diào)整一下代碼執(zhí)行流程,也就是說(shuō)必須先操作本地?cái)?shù)據(jù)庫(kù),再發(fā)送MQ消息。如果本地?cái)?shù)據(jù)庫(kù)SQL執(zhí)行成功,就算MQ消息發(fā)送失敗,MQ還可以重發(fā)。

2.分布式事務(wù)實(shí)現(xiàn)原理

那基于上面的應(yīng)用場(chǎng)景,應(yīng)該如何設(shè)計(jì)發(fā)送消息的流程,才能讓這兩個(gè)操作要么都成功,要么都失敗呢?

其實(shí),可以參照XA兩階段提交的思想,把發(fā)送消息分成兩步,然后把操作本地?cái)?shù)據(jù)庫(kù)也包括在這個(gè)流程中。那么,在介紹原理之前,先科普一下兩個(gè)新的概念:

1、半消息(Half Message):也就是暫不能投遞消費(fèi)者的消息。發(fā)送方已經(jīng)將消息成功發(fā)送到了 MQ 服務(wù)端,但是服務(wù)端未收到生產(chǎn)者對(duì)這條消息的二次確認(rèn),這個(gè)時(shí)候,這條消息會(huì)被標(biāo)記為“暫不能投遞”狀態(tài)。

2、消息回查(Message Status Check):由于網(wǎng)絡(luò)閃斷、生產(chǎn)者應(yīng)用重啟等原因,導(dǎo)致某條事務(wù)消息的二次確認(rèn)丟失,MQ 服務(wù)端通過(guò)掃描發(fā)現(xiàn)某條消息長(zhǎng)期處于“半消息”時(shí),需要主動(dòng)向消息生產(chǎn)者詢(xún)問(wèn)該消息的最終狀態(tài),要么是Commit,要么Rollback。

下面給大家介紹一下RocketMQ的分布式事務(wù)實(shí)現(xiàn)原理,如圖所示,一共分為七個(gè)步驟:

圖片

浪漫和悲觀并不沖突,我時(shí)常消極但又依舊覺(jué)得生活很美好,哪怕只是一束光照進(jìn)了房間,也要認(rèn)真對(duì)待它的到來(lái)。

第一步:生產(chǎn)者向 MQ 服務(wù)端發(fā)送消息。

第二步:MQ 服務(wù)端將消息持久化成功之后,向發(fā)送方 ACK 確認(rèn)消息已經(jīng)發(fā)送成功,此時(shí)消息為半消息。

第三步:發(fā)送方開(kāi)始執(zhí)行本地?cái)?shù)據(jù)庫(kù)事務(wù)邏輯。

第四步:發(fā)送方根據(jù)本地?cái)?shù)據(jù)庫(kù)事務(wù)執(zhí)行結(jié)果向 MQ Server 提交二次確認(rèn),MQ Server 收到 Commit 狀態(tài)則將半消息標(biāo)記為可投遞,訂閱方最終將收到該消息;MQ Server 收到 Rollback 狀態(tài)則刪除半消息,訂閱方將不會(huì)接受該消息。

第五步:在斷網(wǎng)或者是應(yīng)用重啟的特殊情況下,按步驟4提交的二次確認(rèn)最終未到達(dá) MQ Server,經(jīng)過(guò)固定時(shí)間后 MQ Server 將對(duì)該消息發(fā)起消息回查。

第六步:發(fā)送方收到消息回查后,需要檢查對(duì)應(yīng)消息的本地事務(wù)執(zhí)行的最終結(jié)果。

第七步:發(fā)送方根據(jù)檢查得到的本地事務(wù)的最終狀態(tài)再次提交二次確認(rèn),MQ Server 仍按照步驟4對(duì)半消息進(jìn)行操作(Commit/Rollback)。

好了,以上就是我對(duì)RocketMQ分布式事務(wù)的理解。

責(zé)任編輯:武曉燕 來(lái)源: Tom彈架構(gòu)
相關(guān)推薦

2024-01-26 13:17:00

rollbackMQ訂單系統(tǒng)

2022-06-21 08:27:22

Seata分布式事務(wù)

2024-09-02 16:10:19

vue2前端

2022-08-14 07:14:50

Kafka零拷貝

2022-06-10 11:51:49

MySQL事務(wù)隔離

2022-06-30 09:10:33

NoSQLHBaseRedis

2023-11-28 12:25:02

多線程安全

2022-09-06 11:13:16

接口PipelineHandler

2022-09-23 11:00:27

KafkaZookeeper機(jī)制

2025-04-11 09:57:16

2022-07-10 20:24:48

Seata分布式事務(wù)

2019-11-19 08:47:45

Zookeeper分布式事務(wù)

2022-01-26 13:46:40

分布式事務(wù)集合,這

2022-06-27 08:21:05

Seata分布式事務(wù)微服務(wù)

2025-01-15 08:34:00

分布式事務(wù)服務(wù)

2023-09-14 15:44:46

分布式事務(wù)數(shù)據(jù)存儲(chǔ)

2017-07-26 15:08:05

大數(shù)據(jù)分布式事務(wù)

2022-08-28 09:05:34

分布式存儲(chǔ)Ceph

2024-06-13 09:25:14

2022-08-29 16:03:33

狀態(tài)流轉(zhuǎn)Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)