RocketMQ高手之路系列之八:RocketMQ之事务消息(一)

简介: 事务的概念就不用多说了,我相信阅读文章的童鞋都是有着非常深刻的认识。我们都知道MQ可以实现微服务之间的异步以及解耦,那么引入MQ之后,如何实现微服务之间的数据一致性是一个值得思考的问题。事务消息将分为三篇文章进行介绍,本文主要介绍RocketMQ的事务原理,第二篇文章主要分析事务消息源码实现分析。在第三篇文章中将提供一种优化方案,解决RocketMQ对于业务代码侵入较大的问题。

引言

事务的概念就不用多说了,我相信阅读文章的童鞋都是有着非常深刻的认识。我们都知道MQ可以实现微服务之间的异步以及解耦,那么引入MQ之后,如何实现微服务之间的数据一致性是一个值得思考的问题。事务消息将分为三篇文章进行介绍,本文主要介绍RocketMQ的事务原理,第二篇文章主要分析事务消息源码实现分析。在第三篇文章中将提供一种优化方案,解决RocketMQ对于业务代码侵入较大的问题。

  • RocketMQ事务原理
  • 总结

一、RocketMQ事务原理

1、消息发送问题分析

为了方便大家理解,我们以日常生活中的订单服务来进行原理的说明。当我们支付订单之后,我们账户的购物积分也会进行相应的积分调整。我们结合下面的订单服务、RocketMQ、积分服务的简化交互图来看下,如果没有事务消息,这样的服务间交互有没有问题。

image.png

可能有的童鞋会说,这不是很简单嘛,肯定是订单服务先执行本地事务,更新订单信息。然后再发消息到MQ中,积分服务消费消息更新积分啊。但是事实上并没有这么简单。


如果我们订单服务直接更新的了订单信息并进行持久化,而后在发送订单信息到MQ中。如果此时MQ服务不可用,消息发送报错,无法将订单消息发到MQ中,也就意味着积分服务不能收到订单信息,也就不会进行相应的积分操作。此时就会出现订单信息与积分信息数据不一致的问题。那么RocketMQ是怎么解决这个问题的呢?

2、半消息

实际上RocketMQ提供了一种half消息的机制,订单服务发送half消息到MQ中,这个half消息是不被消费者所见的。怎么理解这个half信息呢,按照我自己的理解,就是它实现了一半的消息功能,只在生产端可见,在消费端不可见。那么这个half消息是怎么实现在MQ中不被积分服务所见的呢?


订单服务发送half消息,并不是将消息投递到积分服务订阅的topic,而是将消息投递到RocketMQ中的RMQ_SYS_TRANS_HALF_TOPIC对应的messeageQueue。由于积分服务并没有订阅这个Topic,所以这个消息对于积分服务是不可见的。


另外有个OP_TOPIC用于记录对应half消息的commit/rollback状态。大致的交互如下如所示:

image.png

3、事务消息流程

交代完一些背景知识之后,我们来具体分析下事务消息的流程。订单服务先发送half消息到MQ中,相当于检查下此时RocketMQ是否可用。如果此时half消息可以正常发送到MQ中,订单服务可以收到响应。此时订单服务可以进行本地事务处理,更新订单信息。同时订单服务提供事务执行结果的接口用于RocketMQ进行回调。

image.png

如果订单服务half消息发送失败了,由于网络原因或者MQ挂了,那么此时需要执行一些回滚操作,让订单进行关闭。因为订单信息无法通知到下游服务了。


那么如果half消息已经写入MQ中,但是本地事务执行失败又该怎么办呢?也就是说当订单服务接收到half消息写入成功的响应后,更新订单信息时发生了异常,无法完成状态更新。那么此时订单服务需要发送rollback的请求给RocketMQ,通知其间原来的half信息进行删除。如果本地事务执行成功,则需要发送commit请求给RocketMQ,RocketMQ会将原先存在RMQ_SYS_TRANS_HALF_TOPIC中的消息重新投递到积分服务订阅的TOPIC中去,这样积分服务就可以正常消费信息进行下一步的积分操作了。


再考虑一种情况,如果订单服务发送commit或者rollback请求未正常投递到RocketMQ中,RocketMQ不知道half消息到底是对应的本地事务到底是执行成功了还是执行失败了。针对这种情况,订单服务需要提供状态回查接口,RocketMQ定时检测是否还有没有处理的half消息,当存在这样的消息时,RocketMQ调用会查接口确认本地事务执行情况。执行失败的则删除half消息,执行成功则重新投递消息。


二、总结

最后用一张完整的交互图来总结下事务消息的整体流程,如下所示:

image.png

相关实践学习
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月前
|
消息中间件 Java API
RocketMQ事务消息, 图文、源码学习探究~
介绍 RocketMQ是阿里巴巴开源的分布式消息中间件,它是一个高性能、低延迟、可靠的消息队列系统,用于在分布式系统中进行异步通信。 从4.3.0版本开始正式支持分布式事务消息~ RocketMq事务消息支持最终一致性:在普通消息基础上,支持二阶段的提交能力。将二阶段提交和本地事务绑定,实现全局提交结果的一致性。 原理、流程 本质上RocketMq的事务能力是基于二阶段提交来实现的 在消息发送上,将二阶段提交与本地事务绑定 本地事务执行成功,则事务消息成功,可以交由Consumer消费 本地事务执行失败,则事务消息失败,Consumer无法消费 但是,RocketMq只能保证本地事务
|
5月前
|
消息中间件 Kafka 测试技术
微服务轮子项目(33) -RocketMQ特点、安装部署、异常处理、事务消息原理
微服务轮子项目(33) -RocketMQ特点、安装部署、异常处理、事务消息原理
93 0
|
2月前
|
消息中间件 存储 Apache
精华推荐 | 【深入浅出RocketMQ原理及实战】「性能原理挖掘系列」透彻剖析贯穿RocketMQ的事务性消息的底层原理并在分析其实际开发场景
事务消息(Transactional Message)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败。RocketMQ的事务消息提供类似 X/Open XA 的分布事务功能,通过事务消息能达到分布式事务的最终一致。
364 2
精华推荐 | 【深入浅出RocketMQ原理及实战】「性能原理挖掘系列」透彻剖析贯穿RocketMQ的事务性消息的底层原理并在分析其实际开发场景
|
2月前
|
消息中间件 RocketMQ Docker
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
53 0
|
3月前
|
消息中间件 数据库 RocketMQ
Springboot+RocketMQ通过事务消息优雅的实现订单支付功能
RocketMQ的事务消息,是指发送消息事件和其他事件需要同时成功或同时失败。比如银行转账, A银行的某账户要转一万元到B银行的某账户。A银行发送“B银行账户增加一万元”这个消息,要和“从A银 行账户扣除一万元”这个操作同时成功或者同时失败。RocketMQ采用两阶段提交的方式实现事务消息。
117 0
|
3月前
|
消息中间件 RocketMQ Docker
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)(下)
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
30 0
|
消息中间件 RocketMQ Docker
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)(上)
分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)
69 0
|
3月前
|
存储 消息中间件 关系型数据库
解密分布式事务:CAP理论、BASE理论、两阶段提交(2PC)、三阶段提交(3PC)、补偿事务(TCC)、MQ事务消息、最大努力通知
解密分布式事务:CAP理论、BASE理论、两阶段提交(2PC)、三阶段提交(3PC)、补偿事务(TCC)、MQ事务消息、最大努力通知
|
9月前
|
消息中间件 存储 数据库
七.RocketMQ极简入门-RocketMQ事务消息
RocketMQ极简入门-RocketMQ事务消息
|
6月前
|
消息中间件 存储 Java
消息中间件第五讲:RocketMQ事务消息
消息中间件第五讲:RocketMQ事务消息
122 0