探究RocketMQ事务机制的实现流程,为什么它能做到发送消息零丢失?

RocketMQ系列6——事务消息 RocketMQ在4.3.0版中支持分布式事务消息,这里RocketMQ的事务消息是采用2PC(两段式协议) +补偿机制(消息回查)的分布式事务功能。提供消息发送与业务落库的一致性。 阅读详情

1、解决消息丢失的第一个问题:订单系统推送消息领丢失

既然我们已经明确了消息在基于MQ传输的过程中可能丢失的几个地方,那么我们接着就得一步一步考虑如何去解决各个环节丢失消息的问题,首先要解决的第一个问题,就是订单系统推送消息到MQ的过程中,可能消息就丢失了。

之前我们也说过了,可能在订单系统推送消息到MQ的过程中,就因为常见的网络故障之类的问题,导致消息就丢失了,这里我们可以看一下下图中的示意。

而在RocketMQ中,有一个非常强悍有力的功能,就是事务消息的功能,凭借这个事务级的消息机制,就可以让我们确保订单系统推送给出去的消息一定会成功写入MQ里,绝对不会半路就搞丢了。

今天我们就来系统的分析一下RocketMQ的事务消息机制的原理。

2、发送half消息到MQ去,试探一下MQ是否正常

首先作为我们的订单系统而言,假设他收到了一个订单支付成功的通知之后,他必然是需要在自己的订单数据库里做一些增删改操作的,比如更新订单状态之类的。

可能有的朋友会觉得,订单系统不就是先在自己数据库里做一些增删改操作,然后就直接发个消息到MQ去,让其他关注这个订单支付成功消息的系统去从MQ获取消息做对应的处理就可以了么?

事实上还真不是这么简单。

在基于RocketMQ的事务消息机制中,我们首先要让订单系统去发送一条half消息到MQ去,这个half消息本质就是一个订单支付成功的消息,只不过你可以理解为他这个消息的状态是half状态,这个时候红包系统是看不见这个half消息的,然后我们去等待接收这个half消息写入成功的响应通知

我们看下面的图:

看到这儿可能有的朋友就开始有点郁闷了,可能有的人觉得你没事儿先发个half消息给MQ干什么?

大家先别着急,你可以想一下,假设你二话不说让订单系统直接做了本地的数据库操作,比如订单状态都更新为了已完成,然后你再发送消息给MQ,结果报出一堆异常,发现MQ挂了。

这个时候,必然导致你没法通过消息通知到红包系统去派发红包,那用户一定会发现自己订单支付了,结果红包没收到。

所以,在这里我们首先第一件事,不是先让订单系统做一些增删改操作,而是先发一个half消息给MQ以及收到他的成功的响应,初步先跟MQ做个联系和沟通

大概这个意思就是说,确认一下MQ还活着,MQ也知道你后续可能想发送一条很关键的不希望丢失的消息给他了!

3、万一要是half消息写入失败了呢?

这里我们先来分析第一种情况,万一你订单系统写half消息给MQ就失败了呢?

可能你发现报错了,可能MQ就挂了,或者这个时候网络就是故障了,所以导致你的half消息都没发送成功,总之你现在肯定没法跟MQ通信了。

这个时候你的订单系统就应该执行一系列的回滚操作,比如对订单状态做一个更新,让状态变成“关闭交易”,同时通知支付系统自动进行退款,这才是正确的做法

因为你订单虽然支付了,但是包括派发红包、发送优惠券之类的后续操作是无法执行的,所以此时必然应该把钱款退还给用户,说交易失败了。

这里给大家插播一个我曾经亲身经历过的一个事情,曾经有一次在一家便利店进行购物的时候,我这里都已经显示扫码支付成功了,但是店员那边说在等待他们系统确认

结果等了一会儿,系统显示后台系统有异常,交易失败了,然后过了一会儿就让支付宝自动退款给我了。

其实这就是类似的例子。

4、half消息成功之后,订单系统完成自己的任务

接着我们来考虑第二种情况,你的half消息写成功了,这时你应该干什么呢?

这时你的订单系统就应该在自己本地的数据库里执行一些增删改操作了,因为一旦half消息写成功了,就说明MQ肯定已经收到这条消息了,MQ还活着,而且目前你是可以跟MQ正常沟通的。

我们看下面的图,示意了下一步是订单系统执行自己的增删改操作。

5、如果订单系统的本地事务执行失败了怎么办?

接着我们继续看下一种情况,万一订单系统更新自己的数据库失败了怎么办?

比如订单系统的数据库当时也有网络异常,或者数据库挂了,总而言之,就是你想把订单更新为“已完成”这个状态,是干不成了。

这个时候其实也很简单,直接就是让订单系统发送一个rollback请求给MQ就可以了

这个意思就是说,你可以把之前我发给你的half消息给删除掉了,因为我自己这里都出问题了,已经无力跟你继续后续的流程了。

我们看下面的图,我给出了这个示意:

当然你发送rollback请求给MQ删除那个half消息之后,你的订单系统就必须走后续的回退流程了,就是通知支付系统退款。

当然这里可能还有一些订单系统自己的高可用降级的机制需要考虑,比如数据库无法更新了,此时你可能需要在机器本地磁盘文件里写入订单支付失败的记录。

然后你可以开一个后台线程在MySQL数据库恢复之后 ,再把订单状态更新为“已关闭”。不过这个不在我们讨专栏的范围之内。

6、如果订单系统完成了本地事务之后,接着干什么?

如果订单系统成功完成了本地的事务操作,比如把订单状态都更新为“已完成”了,此时你就可以发送一个commit请求给MQ,要求让MQ对之前的half消息进行commit操作,让红包系统可以看见这个订单支付成功消息

我们看下面的图:

之前我们也提到过了,所谓的half消息实际就是订单支付成功的消息,只不过他的状态是half

也就是说,他是half状态的时候,红包系统是看不见他的,没法获取到这条消息。必须等到订单系统执行commit请求,消息被commit之后,红包系统才可以看到和获取这条消息进行后续处理。

7、让流程严谨一些:如果发送half消息成功了,但是没收到响应呢?

大致的事务消息的流程是讲完了,但是接着让我们来进行比较严谨的分析

如果我们是把half消息发送给MQ了,MQ给保存下来了,但是MQ返回给我们的响应我们没收到呢?此时会发生什么事情?

这个时候我们没收到响应,可能就会网络超时报错,也可能直接有其他的异常错误,这时订单系统会误以为是发送half消息到MQ失败了,订单系统就直接会执行退款流程了,订单状态也会标记为“已关闭”。

我们看下面的图的示意:

但是这时MQ已经存储下来一条half消息了,那对这个消息怎么处理?

其实RocketMQ这里有一个补偿流程,他会去扫描自己处于half状态的消息,如果我们一直没有对这个消息执行commit/rollback操作,超过了一定的时间,他就会回调你的订单系统的一个接口,问问你说,这个消息到底怎么回事?

你到底是打算commit这个消息还是要rollback这个消息?

我们看下图示意:

这个时候我们的订单系统就得去查一下数据库,看看这个订单当前的状态,一下发现订单状态是“已关闭”,此时就知道,你必然是得发送rollback请求给MQ去删除之前那个half消息了!

我们看下图:

8、如果rollback或者commit发送失败了呢?

我们再假设一种场景,如果订单系统是收到了half消息写入成功的响应了,同时尝试对自己的数据库更新了,然后根据失败或者成功去执行了rollback或者commit请求,发送给MQ了

结果因为网络故障,导致rollback或者commit请求发送失败了呢?

这个时候其实也很简单,因为MQ里的消息一直是half状态,所以他过了一定的超时时间会发现这个half消息有问题,他会回调你的订单系统的接口

你此时要判断一下,这个订单的状态如果更新为了“已完成”,那你就得再次执行commit请求,反之则再次执行rollback请求。

本质这个MQ的回调就是一个补偿机制,就怕你的half消息响应没收到,或者rollback、commit请求没发送成功,所以他会来找你问问对half消息后续如何处理。

9、停一下脚本想想上面这个流程的意义在哪里?

看到这里我们来停下脚步想想,上面这个流程的意义在哪里呢?

其实很简单,如果你的MQ有问题或者网络有问题,half消息根本都发不出去,此时half消息肯定是失败的,那么订单系统就不会执行后续流程了!

如果要是half消息发送出去了,但是half消息的响应都没收到,然后执行了退款流程,那MQ会有补偿机制来回调找你询问要commit还是rollback,此时你选择rollback删除消息就可以了,不会执行后续流程!

如果要是订单系统收到half消息了,结果订单系统自己更新数据库失败了,那么他也会进行回滚,不会执行后续流程了!

如果要是订单系统收到half消息了,然后还更新自己数据库成功了,订单状态是“已完成”了,此时就必然会发送commit请求给MQ,一旦消息commit了,那么必然保证红包系统可以收到这个消息!

而且即使你commit请求发送失败了,MQ也会有补偿机制,回调你接口让你判断是否重新发送commit请求

总之,就是你的订单系统只要成功了,那么必然要保证MQ里的消息是commit了可以让红包系统看到他!

所以大家可以结合我们的图思考一下上述流程,通过这套事务消息的机制,是不是就可以保证我们的订单系统一旦成功执行了数据库操作,就一定会通知到红包系统去派发红包?至少订单系统到MQ之间的消息传输是不会有丢失的问题了!

  1. 滴滴开源基于 RocketMQ 的分布式消息队列 DDMQ
  2. 17 个方面,综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四个分布式消息队列
RocketMQ如何保证消息不丢失? 如何快速处理积压消息? 文章目录1. 哪些环节会有丢消息的可能? 1. 哪些环节会有丢消息的可能?         关于MQ,有一个问题是无法避免的,就是怎么保证消息不丢失,这个问题是所有MQ都需要面对的一个共性问题。大致的解决思路都是一致的,首先要找到哪些环节会有丢消息的可能,来看一个MQ的通用架构         其中,1,2,4三个场景分别是:发消息、消息主从同步 阅读详情

相关推荐

保护数据完整性:探索 RocketMQ 分布式事务消息的力量

该篇博文主要分析了 RocketMQ 事务消息流程中的事务 Half 消息发送以及本地事务消息的补偿流程,重点的是结合 GitHub 部分对 RocketMQ 这块的设计部分进行整体了阐述,博主通过时序图+源码具体实现的部分对其进行了更深层次的描述,RocketMQ 源码部分在接收到事务消息时的处理过程以及在对事务消息这一块的补偿处理部分,希望能够加深你对事务消息这块的理解

vnjohn 博主 > 主线分享后端领域业务设计知识、源码思想、架构设计 6544

RocketMQ事务消息

RocketMQ 事务消息

qq_42877546的博客 1万+

RocketMq事务消息(分布式事务解决方案)

从问题出发 阅读本文后,我们将了解以上两个问题的答案。 1、RocketMq生产者组(producer group)的设定有什么用? 2、一个订单处理的场景,消费者订阅了订单topic,但总担心丢消息。于是为了防止丢消息,每天都会通过定时任务做一致性校验,这是最佳方案吗? 这还得从基于消息队列实现实现分布式事务的解决方案说起。 常见的分布式事务包括 2PC、3PC、TCC、本地消息表、消息事务、最大努力通知。 今天我们主要讲讲本地消息表、消息事务两种方案。 本地消息表 本地消息表的大致流程是这样的。 pub

疯狂的蜗牛 9433

RocketMQ事务消息详解

Apache RocketMQ在4.3.0版中已经支持分布式事务消息,采用了2PC(两阶段提交)+ 补偿机制(事务状态回查)的思想来实现了提交事务消息,同时增加一个补偿逻辑来处理二阶段超时或者失败的消息,如下图所示。总的来说,RocketMQ 事务消息在确保消息可靠传递的同时,也需要开发者按照一定的规范来设计和实现本地事务执行器,以及处理可能的回查请求,这些都是在使用 RocketMQ 事务消息时需要考虑和遵循的限制。事务消息的生产者 ID 不能与其他类型消息的生产者 ID 共享。

刘皇叔说Java的博客 4140

RocketMQ 是如何使用事务消息保证发送消息不丢失的

rocketmq 消息队列在大部分业务系统中都会用到,使用方式也很简单,调用producer接口向broker发送消息,创建consumer实例消费broker上的消息。不知道大家有没有想过,broker是可靠的吗,producer发送的消息一定会成功吗,consumer一定会消费到这条消息吗?消息会不会在哪个环节丢失,如果丢失了对业务会没有影响,我们有应该怎么解决。下面就从producer,br...

trntaken的博客 1265

RocketMQ篇四(保证消息不丢失、保证消息顺序、快速处理消息积压、消息轨迹、消息位点)

1. RocketMQ如何保证消息不丢失 1.1 Producer端 1.1.1 同步发送、重试3次、集群部署 1.1.2 生产者使用事务消息机制保证消息零丢失 1.2 Broker同步刷盘+Dledger主从架构保证MQ自身不会丢消息 1.3 Consumer消费者端消费确认 1.4 RocketMQ特有的问题:NameServer挂了如何保证消息不丢失? 1.5 RocketMQ消息零丢失方案总结 2. 使用RocketMQ如何保证消息顺序 3. RocketMQ如何快速处理积压消息 4. Rocket

xingze的博客 3313

RocketMQ之三----事务消息

根据半事务消息Topic RMQ_SYS_TRANS_HALF_TOPIC 和处理半事务消息Topic RMQ_SYS_TRANS_OP_HALF_TOPIC 差值判断需要回查的半事务消息,发CHECK_TRANSACTION_STATE回查指令到业务方查询本地事务执行结果。RMQ_SYS_TRANS_OP_HALF_TOPIC 已处理的半事务消息topic,body存的是半事务消息Topic 的消息位移,同一个queue下,用逗号分隔(另有线程处理)然后保存并返回结果(到此完成发送半事务消息)。

枫火的博客 2970

RocketMQ - 发送消息零丢失方案:RocketMQ事务消息的实现流程分析

RocketMQ有一个非常强悍有力得到功能,就是事务消息,凭借这个事务级的消息机制,就可以让我们保证生产者推送出去的消息一定会成功写入MQ里,绝不会半路就搞丢了。首先以一个订单系统为例,假设他收到了一个订单支付成功的通知之后,他必然是需要在自己的订单数据库里做一些增删改查操作的,比如更新订单状态之类的。可能你会觉得,订单系统不就是先在自己的数据库做一些操作,然后直接发个消息到MQ去,让其他订阅这个Topic的系统去从MQ获取消息做对应的处理就可以了吗?其实还真不是这么简单,在基于RocketMQ的事务消息机

yang的博客 572

科普文:微服务之Spring Cloud Alibaba消息队列组件RocketMQ工作原理

事务消息是为了保证分布式系统中消息的一致性而引入的一种消息类型。事务消息允许消息发送方在发送消息后,进行本地事务操作,并根据本地事务的执行结果来决定消息的最终状态(提交或回滚)。

为无为,事无事,味无味。 1299

从入门到精通:MATEKH743 飞控全解析——MAVLink 接口软/硬件对接实战

MATEKH743飞控是基于STM32H743微控制器的无人机核心控制系统,具备强大计算能力和丰富外设接口。该飞控采用双核架构,集成高性能IMU、气压计等传感器,支持多种开源固件(Betaflight/INAV/ArduPilot),适用于FPV穿越机、固定翼及工业无人机。相比PX4等飞控,MATEKH743在性价比和DIY友好度上优势明显,同时支持MAVLink协议实现设备通信。未来发展方向包括集成更高精度传感器、优化电源管理以及拓展工业应用场景,持续推动无人机技术创新。

bother3000的博客 2284

Windows服务器SSL漏洞修复实战:如何一键禁用TLS 1.0/1.1避免SWEET32攻击

本文提供了Windows服务器修复SWEET32漏洞的实战指南。通过组策略编辑器,详细讲解如何一键禁用不安全的TLS 1.0/1.1协议,并优化密码套件顺序,以消除由3DES等弱加密算法带来的安全风险。文章还涵盖了应对SQL Server等应用兼容性挑战的解决方案,以及企业级批量部署的脚本化方法,帮助管理员系统性地提升服务器TLS/SSL安全配置。

weixin_29310631的博客 246

深入探究 RocketMQ 事务机制的实现流程,为什么它能做到发送消息零丢失?

公众号后台回复“学习”,免费获取精品学习资料扫描下方海报试听本文来自狸猫技术窝专栏《从零开始带你成为消息中间件实战高手》,是作者原子弹大侠开放的试读1、解决消息丢失的第一个问题:订单系...

石杉的架构笔记 880

Frida+Objection保姆级教程:从环境搭建到实战Hook(含Wallbreaker插件使用)

本文提供了一份从零开始的Frida与Objection移动安全动态分析实战指南。详细讲解了Python环境配置、Frida-Server部署、Objection核心命令使用以及Wallbreaker插件安装与应用。通过实战案例演示如何Hook网络请求(如HttpURLConnection和OkHttp3),帮助安全研究人员快速掌握应用运行时行为分析与漏洞挖掘技能。

weixin_28318011的博客 101

ibm linux mq 发送消息_探究 RocketMQ 事务机制的实现流程,为什么能做到发送消息零丢失...

1、解决消息丢失的第一个问题:订单系统推送消息领丢失既然我们已经明确了消息在基于MQ传输的过程中可能丢失的几个地方,那么我们接着就得一步一步考虑如何去解决各个环节丢失消息的问题,首先要解决的第一个问题,就是订单系统推送消息到MQ的过程中,可能消息就丢失了。之前我们也说过了,可能在订单系统推送消息到MQ的过程中,就因为常见的网络故障之类的问题,导致消息就丢失了,这里我们可以看一下下图中的示意。而在R...

weixin_39668408的博客 160

【GB28181】wvp-GB28181-pro部署安装教程(Ubuntu平台)

初始环境安装。

废人一枚的博客 5082

手把手教你学Simulink--基于电能质量与无功补偿的场景实例:统一电能质量调节器(UPQC)的联合控制仿真

在现代电力系统中,电能质量问题有源电力滤波器(APF)→ 治理谐波与无功动态电压恢复器(DVR)→ 补偿电压暂降/暂升静止无功发生器(SVG)→ 无功补偿与电压支撑而统一电能质量调节器(Unified Power Quality Conditioner, UPQC)是一种集串联补偿与并联补偿于一体的全能型电能质量治理装置✅ 电压类问题:暂降、暂升、不平衡、闪变✅ 电流类问题:谐波、无功、三相不平衡✅ 实现双向有功交换(储能型)串联单元(DVR功能):串联于线路,控制电源侧电压质量并联单元。

MHD0815的博客 239

RocketMQ消息丢失场景及解决办法

既然使用在项目中使用了MQ,那么就不可避免的需要考虑消息丢失问题。在一些涉及到了金钱交易的场景下,消息丢失还是很致命的。那么在RocketMQ中存在哪几种消息丢失的场景呢? 先来一张最简单的消费流程图: 上图中大致包含了这么几种场景: 生产者产生消息发送给RocketMQ RocketMQ接收到了消息之后,必然需要存到磁盘中,否则断电或宕机之后会造成数据的丢失 消费者从RocketMQ中获取消...

LO_YUN的博客 2万+

IsaacSim环境配置之配置本地资产包

摘要:Isaac Sim官方资产文件默认从美国服务器下载速度慢,影响开发体验。建议下载本地资产包并配置本地资源源。具体步骤包括:1) 下载资产包并解压;2) 修改Isaac Sim安装路径下的配置文件,添加本地资产路径配置,包括机器人、人物、环境等各类资源目录。配置完成后可显著提升资产加载速度,改善开发效率。文中提供了详细的配置文件修改示例和截图说明。

拥抱具身智能,昇腾Ascend C 330

RocketMQ发送消息之事务消息

官网上说这种机制类似于X/Open XA的分布式事务功能,通过事务消息达到分布式事务的最终一致性。RocketMQ在4.3.0版本中首次引入了分布式事务消息的功能。

小威的博客 8664

【乐鑫】唤醒词修改方法

乐鑫科技的语音识别模块(如ESP-SR)支持自定义唤醒词,但需通过官方工具链完成。

以实战经验介绍行业知识 827

YOLOv8改进 | Conv篇 | 轻量级下采样方法ContextGuided(大幅度涨点)

ContextGuided通过创新的局部-全局协同机制,解决了传统下采样方法中细节丢失与上下文缺失的核心痛点。实验证明其在YOLOv8上可实现最高2.6%的mAP提升,且计算开销增加不足5%。这种即插即用的设计为实时目标检测系统提供了新的优化方向。创新启示:轻量化不代表简单裁剪,智能信息融合才是未来方向!下一步探索与Transformer结合构建混合架构多尺度上下文融合机制3D点云中的扩展应用资源获取完整训练代码:[GitHub链接]预训练模型:[Google Drive链接]讨论话题。

QQ_778132974的博客 289

27 发送消息零丢失方案:RocketMQ事务消息的实现流程分析

1.解决消息丢失的第一个问题:订单系统推送消息丢失 当前的问题,在订单系统推送消息到MQ的过程中,就因为常见的网络故障之类的问题,导致消息就丢失了。 在RocketMQ中,有这么一个功能,就是事务消息的功能,凭借这个事务级的消息机制,就可以让我们确保订单系统推送出去的消息一定会成功写入MQ里,绝对不会半路就搞丢了。 2.事务消息:half消息 在基于RocketMQ的事务消息机制中,我们首先要让订单系统去发送一条half消息到MQ去,这个half消息本质就是一个订单支付成功的消息,只不过可以理解

喜欢历史的码农 2680

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

rocketmq如何保证消息不丢失

一、大体可以从三方面来说: 分别从Producer发送机制、Broker的持久化机制,以及消费者的offSet机制来最大程度保证消息不易丢失 从Producer的视角来看:如果消息未能正确的存储在MQ中,或者消费者未能正确的消费到这条消息,都是消息丢失。 从Broker的视角来看:如果消息已经存在Broker里面了,如何保证不会丢失呢(宕机、磁盘崩溃) 从Consumer的视角来看:如果消...

leeasony的博客 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

RocketMQ实战—4.消息零丢失的方案

但是从订单系统和红包系统当天那个时间段的日志来看,居然只看到订单系统推送消息到RocketMQ的日志,却没看到红包系统从RocketMQ中消费消息以及发现金红包的日志。所以订单系统在收到订单支付成功的通知后做的第一件事,不是先让订单系统做一些增删改操作,而是先发一个half消息给RocketMQ以及等待它的成功响应,也就是初步和RocketMQ建立联系和沟通,从而让订单系统确认RocketMQ还活着,RocketMQ也会知道订单系统后续可能想发送一条很关键的不希望丢失的消息给它。

mjunz的博客 1162

浅谈RocketMQ如何保证消息不丢失

RocketMQ如何保证消息不丢失?一、明确丢失消息场景二、RocketMQ避免消息丢失解决方案1、消息生产者使用事务消息2、配置同步刷盘+Dledger主从架构3、消息消费者端使用同步消费机制4、设计降级方案 MQ如何避免消息不丢失,这个问题是所有MQ都需要面对的一个共性问题。大致的解决思路都是一致的,但是针对不同的MQ产品又有不同的解决方案。分析这个问题可以从以下几个角度入手。 一、明确丢失消息场景 下图是基础的MQ系统架构。 其中,1,2,4三个场景都是跨网络的,跨网络就肯定会有丢消息的可能。

持续Java学习中 5934
上一篇: 猪场安卓一期架构
下一篇: SpringCloud Eureka源码分析
代码兄弟
博客等级 码龄11年 53粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值