1.前言
此文章是在儒猿课程中的学习笔记,感兴趣的想看原来的课程可以去咨询儒猿课堂
这篇文章紧挨着上一篇博客来进行编写,有些不清楚的可以看下上一篇博客:
2.事务消息的底层逻辑
像上述的场景,订单系统发送一个half消息到RocketMQ集群中的时候,当我们发送消息到RocketMQ上的时候,我们会把消息存储到某个Broker上的CommitLog文件中,同时将索引写到某个MessageQueue的某个ConsumeQueue文件上。如果按照正常的逻辑写到这个上面的话,下游的系统就会消费到你所发送的Half消息,为了保证下游系统消费不到,RocketMQ是是不会将offset进行保存的到MessageQueue的某个ConsumeQueue文件上,而是保存到了自己内部的一个topic:“RMQ_SYS_TRANS_HALF_TOPIC”对应的一个ConsumeQueue文件上。写入到这个内部的Topic之后就可以返回写入Half消息成功
如果因为各种问题没有进行Commit/RollBack,RocketMQ内部会有一个定时任务,会去扫描RMQ_SYS_TRANS_HALF_TOPIC中超过一定时间状态还未进行变更的Half消息,会进行回调业务系统的接口,进行判断该条消息是rollback,还是commit
如果是rollback,如何进行标记half消息的回滚呢,会把之前的消息进行删除吗?答案是不会的,因为RocketMQ都是顺序写入磁盘的,此时你要进行回滚操作的时候,其本质就是OP标识一下这个Half消息的状态,RocketMQ内部是有一个OP_TOPIC,会写一条rollback记录到OP_TOPIC里,用来标记half消息回滚了。顺便再提一下,就是如果一直长时间不进行rollback/commit的话,rocketmq会进行回调业务系统接口来进行判断half消息的状态,但是它是有一个最大的回调次数(15次),如果超过这个次数,那么它就会任务half消息的状态为rollback。
如果是commit,如何让下游系统能进行消费到呢,这个操作就比较简单了,首先会先向OP_TOPIC中进行写入一条记录,用来标记Half消息已经commit,同时会向真正的topic的consumequeue文件进行写入数据。