跳槽高级开发就这么答:谈谈你对RocketMQ分布式事务原理的理解

简介: 有位工作五年的小伙伴在面试的时候被问到RocketMQ的分布式事务实现原理。他说他只知道RocketMQ能够支持事务,但是没有了解过它的事务实现原理。今天,我给大家分享一下我对这个问题的理解。

有位工作五年的小伙伴在面试的时候被问到RocketMQ的分布式事务实现原理。他说他只知道RocketMQ能够支持事务,但是没有了解过它的事务实现原理。


今天,我给大家分享一下我对这个问题的理解。

1 分布式事务应用场景

随着应用的拆分,从单体架构变成分布式架构,那么每个服务或者模块也会有自己的数据库。一个业务流程的完成需要经过多次的接口调用或者多条MQ消息的发送。

bd1afff6341d3cb310a7ca58f27f4e96.jpg

那么问题来了,如果是执行多条SQL语句,数据库的本地事务可以保证原子性。

9bb293f9b6b188323b8099e40ccccc30.jpg

但,如果是一条SQL操作,再加一条MQ的操作,如何才能把它们两个放在同一个逻辑单元里面执行呢?是先执行SQL还是先发送MQ呢?

d9cb6f4a928d8e60991c6a1974cdafda.jpg

我们来分析一下情况,如果是先发送MQ消息,再执行SQL。这个时候就要分为两种情况:


第1种情况:如果发送MQ失败了,当然SQL也就不会执行了。


第2种情况:如果发送MQ成功了,而本地数据库SQL执行失败。比如出现了网络异常,主键重复或者字段超长等等。

d8ccc2f4c542e9ced72ca68ea9476588.jpg

也就是说,下游的业务系统拿到了最新的数据,而自己本地的数据库反而没有。这个时候,本地数据库的数据跟其他系统已经登记的数据就不一样了,而发出去的消息又不可能撤回,有可能已经被消费了,这个叫做覆水难收。

79ee01c053f5b5e56b6655735885af79.jpg

因此,在分布式应用场景中,我们需要调整一下代码执行流程,也就是说必须先操作本地数据库,再发送MQ消息。如果本地数据库SQL执行成功,就算MQ消息发送失败,MQ还可以重发。

2 分布式事务实现原理

那基于上面的应用场景,应该如何设计发送消息的流程,才能让这两个操作要么都成功,要么都失败呢?


其实,可以参照XA两阶段提交的思想,把发送消息分成两步,然后把操作本地数据库也包括在这个流程中。那么,在介绍原理之前,先科普一下两个新的概念:


1、半消息(Half Message):也就是暂不能投递消费者的消息。发送方已经将消息成功发送到了 MQ 服务端,但是服务端未收到生产者对这条消息的二次确认,这个时候,这条消息会被标记为“暂不能投递”状态。


2、消息回查(Message Status Check):由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,MQ 服务端通过扫描发现某条消息长期处于“半消息”时,需要主动向消息生产者询问该消息的最终状态,要么是Commit,要么Rollback。


下面给大家介绍一下RocketMQ的分布式事务实现原理,如图所示,一共分为七个步骤:

53a78cff07e7f6364a303090ad7a5ec5.jpg

第一步:生产者向 MQ 服务端发送消息。


第二步:MQ 服务端将消息持久化成功之后,向发送方 ACK 确认消息已经发送成功,此时消息为半消息。


第三步:发送方开始执行本地数据库事务逻辑。


第四步:发送方根据本地数据库事务执行结果向 MQ Server 提交二次确认,MQ Server 收到 Commit 状态则将半消息标记为可投递,订阅方最终将收到该消息;MQ Server 收到 Rollback 状态则删除半消息,订阅方将不会接受该消息。


第五步:在断网或者是应用重启的特殊情况下,按步骤4提交的二次确认最终未到达 MQ Server,经过固定时间后 MQ Server 将对该消息发起消息回查。


第六步:发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。


第七步:发送方根据检查得到的本地事务的最终状态再次提交二次确认,MQ Server 仍按照步骤4对半消息进行操作(Commit/Rollback)。


好了,以上就是我对RocketMQ分布式事务的理解。


我是被编程耽误的文艺Tom,关注我,面试不再难!

3c2047b0ee454886b4e6edf75f6c98c3.gif

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
2月前
|
消息中间件 RocketMQ 微服务
RocketMQ 分布式事务消息实战指南
RocketMQ 分布式事务消息实战指南
280 1
|
2月前
|
存储 数据采集 监控
SkyWalking全景解析:从原理到实现的分布式追踪之旅
SkyWalking全景解析:从原理到实现的分布式追踪之旅
388 1
|
1月前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
34 0
|
1月前
|
消息中间件 存储 安全
【深入浅出RocketMQ原理及实战】「底层原理挖掘系列」透彻剖析贯穿RocketMQ的消息顺序消费和并发消费机制体系的原理分析
【深入浅出RocketMQ原理及实战】「底层原理挖掘系列」透彻剖析贯穿RocketMQ的消息顺序消费和并发消费机制体系的原理分析
28 0
|
2月前
|
消息中间件 存储 负载均衡
分布式消息传递新时代:深入了解RabbitMQ_sharding插件的精髓【RabbitMQ 八】
分布式消息传递新时代:深入了解RabbitMQ_sharding插件的精髓【RabbitMQ 八】
42 0
|
2天前
|
消息中间件 测试技术 数据库
基于RocketMQ实现分布式事务(下)
基于RocketMQ实现分布式事务(上)
15 0
|
2天前
|
消息中间件 Java 测试技术
基于RocketMQ实现分布式事务(上)
基于RocketMQ实现分布式事务(上)
15 0
|
6天前
|
存储 NoSQL 分布式数据库
【Flink】Flink分布式快照的原理是什么?
【4月更文挑战第21天】【Flink】Flink分布式快照的原理是什么?
|
1月前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解
|
1月前
|
存储 Java 应用服务中间件
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
54 0