成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

RocketMQ 事務(wù)消息初體驗(yàn)

開發(fā) 前端
假如先發(fā)送消息,后修改訂單狀態(tài),消息發(fā)送成功,訂單沒有執(zhí)行成功,需要回滾整個事務(wù)(訂單數(shù)據(jù)事務(wù)回滾,積分服務(wù)消費(fèi)時,需要先反查事務(wù)狀態(tài),若事務(wù)提交,才能插入積分記錄)。

事務(wù)消息是 RocketMQ 的高級特性之一 。這篇文章,筆者會從應(yīng)用場景、功能原理、實(shí)戰(zhàn)例子三個模塊慢慢為你揭開事務(wù)消息的神秘面紗。

1 應(yīng)用場景

舉一個電商場景的例子:用戶購物車結(jié)算時,系統(tǒng)會創(chuàng)建支付訂單。

用戶支付成功后支付訂單的狀態(tài)會由未支付修改為支付成功,然后系統(tǒng)給用戶增加積分。

通常我們會使用普通消費(fèi)方案,該方案能夠發(fā)揮 MQ 的優(yōu)勢:異步和解耦 ,  同時架構(gòu)設(shè)計(jì)非常簡單。

圖片圖片

  1. 用戶購物車結(jié)算時,系統(tǒng)創(chuàng)建支付訂單;
  2. 支付成功后,更新訂單的狀態(tài)從未支付修改為支付成功;
  3. 發(fā)送一條普通消息到消息隊(duì)列服務(wù)端;
  4. 積分服務(wù)消費(fèi)消息,添加積分記錄。

但該方案有個非常直觀的缺點(diǎn):容易出現(xiàn)不一致的現(xiàn)象。

  1. 假如先發(fā)送消息,后修改訂單狀態(tài),消息發(fā)送成功,訂單沒有執(zhí)行成功,需要回滾整個事務(wù)(訂單數(shù)據(jù)事務(wù)回滾,積分服務(wù)消費(fèi)時,需要先反查事務(wù)狀態(tài),若事務(wù)提交,才能插入積分記錄)。
  2. 假如先修改訂單狀態(tài),后發(fā)送消息,訂單狀態(tài)修改成功,但消息發(fā)送失敗,需要補(bǔ)償操作才能保持最終一致。
  3. 假如先修改訂單,后發(fā)送消息,訂單狀態(tài)修改成功,但消息發(fā)送超時,此時無法判斷需要回滾訂單還是提交訂單變更。

我們看到,為了完善普通消費(fèi)方案,業(yè)務(wù)層還需要做到兩點(diǎn):補(bǔ)償機(jī)制和提供事務(wù)狀態(tài)查詢接口。

要做到這兩點(diǎn),難不難呢?

不難,但是業(yè)務(wù)層代碼會比較混亂,更優(yōu)的方案還是得從中間件層面解決。

2 功能原理

RocketMQ 事務(wù)消息是支持在分布式場景下保障消息生產(chǎn)和本地事務(wù)的最終一致性。交互流程如下圖所示:

圖片圖片

1、生產(chǎn)者將消息發(fā)送至 Broker 。

2、Broker 將消息持久化成功之后,向生產(chǎn)者返回 Ack 確認(rèn)消息已經(jīng)發(fā)送成功,此時消息被標(biāo)記為"暫不能投遞",這種狀態(tài)下的消息即為半事務(wù)消息。

3、生產(chǎn)者開始執(zhí)行本地事務(wù)邏輯。

4、生產(chǎn)者根據(jù)本地事務(wù)執(zhí)行結(jié)果向服務(wù)端提交二次確認(rèn)結(jié)果( Commit 或是 Rollback ),Broker 收到確認(rèn)結(jié)果后處理邏輯如下:

  • 二次確認(rèn)結(jié)果為 Commit :Broker 將半事務(wù)消息標(biāo)記為可投遞,并投遞給消費(fèi)者。
  • 二次確認(rèn)結(jié)果為 Rollback :Broker 將回滾事務(wù),不會將半事務(wù)消息投遞給消費(fèi)者。

5、在斷網(wǎng)或者是生產(chǎn)者應(yīng)用重啟的特殊情況下,若 Broker 未收到發(fā)送者提交的二次確認(rèn)結(jié)果,或 Broker 收到的二次確認(rèn)結(jié)果為 Unknown 未知狀態(tài),經(jīng)過固定時間后,服務(wù)端將對消息生產(chǎn)者即生產(chǎn)者集群中任一生產(chǎn)者實(shí)例發(fā)起消息回查。

  1. 生產(chǎn)者收到消息回查后,需要檢查對應(yīng)消息的本地事務(wù)執(zhí)行的最終結(jié)果。
  2. 生產(chǎn)者根據(jù)檢查到的本地事務(wù)的最終狀態(tài)再次提交二次確認(rèn),服務(wù)端仍按照步驟4對半事務(wù)消息進(jìn)行處理。

筆者認(rèn)為事務(wù)消息的精髓在于:

  1. 本地事務(wù)執(zhí)行成功,消費(fèi)者才能消費(fèi)事務(wù)消息;
  2. 消息回查本身就是補(bǔ)償機(jī)制的實(shí)現(xiàn),事務(wù)生產(chǎn)者需提供了事務(wù)狀態(tài)查詢接口。

3 實(shí)戰(zhàn)例子

為了便于大家理解事務(wù)消息 ,筆者新建一個工程用于模擬支付訂單創(chuàng)建、支付成功、贈送積分的流程。

首先,我們創(chuàng)建一個真實(shí)的訂單主題:order-topic 。

圖片圖片

然后在數(shù)據(jù)庫中創(chuàng)建三張表 訂單表、事務(wù)日志表、積分表。

圖片圖片

最后我們創(chuàng)建一個 Demo 工程,生產(chǎn)者模塊用于創(chuàng)建支付訂單、修改支付訂單成功,消費(fèi)者模塊用于新增積分記錄。

圖片圖片

接下來,我們展示事務(wù)消息的實(shí)現(xiàn)流程。

1、創(chuàng)建支付訂單

調(diào)用訂單生產(chǎn)者服務(wù)創(chuàng)建訂單接口 ,在 t_order 表中插入一條支付訂單記錄。

圖片圖片

2、調(diào)用生產(chǎn)者服務(wù)修改訂單狀態(tài)接口

接口的邏輯就是執(zhí)行事務(wù)生產(chǎn)者的 sendMessageInTransaction  方法。

圖片圖片

生產(chǎn)者端需要配置事務(wù)生產(chǎn)者和事務(wù)監(jiān)聽器。

圖片圖片

發(fā)送事務(wù)消息的方法內(nèi)部包含三個步驟 :

圖片圖片

事務(wù)生產(chǎn)者首先發(fā)送半事務(wù)消息,發(fā)送成功后,生產(chǎn)者才開始執(zhí)行本地事務(wù)邏輯。

事務(wù)監(jiān)聽器實(shí)現(xiàn)了兩個功能:執(zhí)行本地事務(wù)和供 Broker 回查事務(wù)狀態(tài) 。

圖片圖片

執(zhí)行本地事務(wù)的邏輯內(nèi)部就是執(zhí)行 orderService.updateOrder 方法。

方法執(zhí)行成功則返回 LocalTransactionState.COMMIT_MESSAGE , 若執(zhí)行失敗則返回 LocalTransactionState.ROLLBACK_MESSAGE 。

圖片圖片

需要注意的是: orderService.updateOrder 方法添加了事務(wù)注解,并將修改訂單狀態(tài)和插入事務(wù)日志表放進(jìn)一個事務(wù)內(nèi),避免訂單狀態(tài)和事務(wù)日志表的數(shù)據(jù)不一致。

最后,生產(chǎn)者根據(jù)本地事務(wù)執(zhí)行結(jié)果向 Broker 提交二次確認(rèn)結(jié)果。

Broker 收到生產(chǎn)者確認(rèn)結(jié)果后處理邏輯如下:

  • 二次確認(rèn)結(jié)果為 Commit :Broker 將半事務(wù)消息標(biāo)記為可投遞,并投遞給消費(fèi)者。
  • 二次確認(rèn)結(jié)果為 Rollback :Broker 將回滾事務(wù),不會將半事務(wù)消息投遞給消費(fèi)者。

3、積分消費(fèi)者消費(fèi)消息,添加積分記錄

當(dāng) Broker 將半事務(wù)消息標(biāo)記為可投遞時,積分消費(fèi)者就可以開始消費(fèi)主題 order-topic 的消息了。

圖片圖片

積分消費(fèi)者服務(wù),我們定義了消費(fèi)者組名,以及訂閱主題和消費(fèi)監(jiān)聽器。

圖片圖片

在消費(fèi)監(jiān)聽器邏輯里,冪等非常重要 。當(dāng)收到訂單信息后,首先判斷該訂單是否有積分記錄,若沒有記錄,才插入積分記錄。

而且我們在創(chuàng)建積分表時,訂單編號也是唯一鍵,數(shù)據(jù)庫中也必然不會存在相同訂單的多條積分記錄。

4 總結(jié)

RocketMQ 事務(wù)消息是支持在分布式場景下保障消息生產(chǎn)和本地事務(wù)的最終一致性。

編寫一個實(shí)戰(zhàn)例子并不復(fù)雜,但使用事務(wù)消息時需要注意如下三點(diǎn):

1、事務(wù)生產(chǎn)者和消費(fèi)者共同協(xié)作才能保證業(yè)務(wù)數(shù)據(jù)的最終一致性;

2、事務(wù)生產(chǎn)者需要實(shí)現(xiàn)事務(wù)監(jiān)聽器,并且保存事務(wù)的執(zhí)行結(jié)果(比如事務(wù)日志表) ;

3、消費(fèi)者要保證冪等。消費(fèi)失敗時,通過重試、告警+人工介入等手段保證消費(fèi)結(jié)果正確。

筆者會在后續(xù)的文章里,詳細(xì)解析事務(wù)消息的實(shí)現(xiàn)原理,敬請期待。

實(shí)戰(zhàn)代碼地址:

https://github.com/makemyownlife/rocketmq4-learning

責(zé)任編輯:武曉燕 來源: 勇哥java實(shí)戰(zhàn)分享
相關(guān)推薦

2024-10-29 08:34:27

RocketMQ消息類型事務(wù)消息

2021-10-03 21:41:13

RocketMQKafkaPulsar

2021-04-15 09:17:01

SpringBootRocketMQ

2009-08-01 09:06:35

UbuntuOneLinux開源操作系統(tǒng)

2009-03-09 15:12:39

XenServer安裝

2024-02-04 09:02:29

RocketMQ項(xiàng)目處理器

2023-07-15 08:01:38

2010-11-22 10:31:17

Sencha touc

2011-05-30 15:12:10

App Invento 初體驗(yàn)

2023-09-04 08:00:53

提交事務(wù)消息

2009-11-30 10:09:02

谷歌Chrome OS

2011-08-02 10:26:59

iOS 多線程 線程

2011-11-01 10:30:36

Node.js

2013-06-08 10:15:29

Outlook 201Outlook 201

2011-09-15 15:03:10

2010-12-13 11:39:39

2025-03-18 07:30:41

2017-09-05 05:55:24

AWS ES集群大數(shù)據(jù)

2011-09-05 10:20:21

Sencha ToucAPP

2009-07-21 13:08:08

iBATIS DAO
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 嫩草伊人| 无码一区二区三区视频 | 91正在播放| 日韩在线小视频 | 亚洲毛片在线观看 | 亚洲综合免费 | 久久精品成人热国产成 | 亚洲精品视频久久 | 91五月婷蜜桃综合 | 久久国产精品99久久久大便 | 国产精品亚洲精品日韩已方 | 色橹橹欧美在线观看视频高清 | 狠狠爱视频 | 国产成人精品一区二区三区在线 | 久久久久无码国产精品一区 | 中文字幕日韩欧美一区二区三区 | 国产精品欧美日韩 | 国产免费一区二区三区 | 欧美国产日韩在线观看 | 中国av在线免费观看 | 国产精品欧美一区二区 | 精品久久99 | 亚洲精品9999| 久久久精品久久 | 黄色综合| 国产精品.xx视频.xxtv | 欧美中文字幕一区二区三区 | 五月天婷婷激情 | 日韩一区二区免费视频 | 日韩高清中文字幕 | 日韩国产一区二区 | 秋霞在线一区二区 | 网色 | 亚洲精品国产精品国自产在线 | 国产精品久久久久久久久久三级 | 91精品国产乱码麻豆白嫩 | 日本a在线| 99久久精品免费看国产小宝寻花 | 亚洲日韩中文字幕一区 | 国精日本亚洲欧州国产中文久久 | 高清国产午夜精品久久久久久 |