68
社区成员




这里主要是参考RocketMQ官方文档里面的内容,参考地址:
http://rocketmq.apache.org/rocketmq/the-design-of-transactional-message/
Half(Prepare) Message
指的是暂不能投递的消息,发送方已经将消息成功发送到了 MQ 服务端,但是服务端未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,处于该种状态下的消息即半消息。
消息回查
由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,MQ 服务端通过扫描发现某条消息长期处于“半消息”时,需要主动向消息生产者询问该消息的最终状态(Commit 或是 Rollback),该过程即消息回查。
事务消息发送对应步骤1、2、3、4,事务消息回查对应步骤5、6、7。
第一感觉和定时消息做法非常类似,但是比定时消息要复杂。定时消息内容在:RocketMQ(九):消息发送(续)里面提到过。
本质: 定时消息先把定时消息的topic修改为SCHEDULE_TOPIC_XXXX,之后一系列处理……,我们这个事务消息也是一样,先发送Half(Prepare) Message消息的时候,其实topic内容也继续了修改(RMQ_SYS_TRANS_HALF_TOPIC),所有consumer是不可见的(如果提交就用真实topic,如果需要回滚那么就那临时的topic内容删除即可。)
Half(Prepare) Message修改topic断点如下:
本篇仅仅是一个入门介绍,里面具体细节后续章节会进行分析。
思考: 如果把发送普通消息和本地执行逻辑放在一个事务里面,如果执行事务成功就发送普通消息,如果失败就回滚好像也是可以,那么这种事务消息相对其有什么优势或者好处呢??? 思考下。
其实这个内容在,RocketMQ事务消息介绍里面也说明了,由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,MQ 服务端通过扫描发现某条消息长期处于“半消息”时,需要主动向消息生产者询问该消息的最终状态(Commit 或是 Rollback),该过程即消息回查。那么RocketMQ到底怎么做的呢?下面马上就会介绍。
每60s会对Half(Prepare) Message的topic主题为RMQ_SYS_TRANS_HALF_TOPIC的消息进行check。
broker会调用自己实现TransactionListener接口的checkLocalTransaction方法。
备注: 就是RocketMQ已经实现这个机制,今天这篇仅仅是入门介绍,并没有涉及到很多细节,先把大概流程说明白,后续再具体细节进行开篇说明。
在RocketMQ事务消息如何使用的时候我们提到,**如果消费失败怎么办?**消费失败有2种,第一种是超时了,我们重试即可,第二种是真的处理失败了?仔细思考下,这块还是蛮复杂的,假如需要有7-8个业务模块呢,其中执行到第6个业务模块就失败呢? **这种重试好几次还是失败,我们该如何处理呢???**是回滚前面5个操作吗?好复杂好复杂,为什么RocketMQ不提供自动回滚呢? 希望大家思考下,如果失败率比较大,那么就是系统问题需要优化代码业务……