RocketMQ事务机制的底层实现原理解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RocketMQ事务机制的底层实现原理解析相关的知识,希望对你有一定的参考价值。

参考技术A

我们之前都分析过,我们发送一条消息到MQ时,会先创建一个topic,假设这个topic叫OrderPaySuccessTopic,然后把消息发送到这个topic中,然后通过MQ内部的流程,流入到某个broker的MessageQueue中,然后完整的数据信息写入commitLog中,把offset偏移量信息写入ConsumeQueue中,然后消费者订阅这个topic,就可以消费消息,但是当我们发送half消息的时候,为什么消费者就消费不到呢;其本质的一个原因就是RocketMQ一旦发现你发送的是一条half消息,它不会把这个half消息的offset写入OrderPaySuccessTopic中的ConsumeQueue里去,它会把这条half消息写入到自己内部的一个 “RMQ_SYS_TRANS_HALF_TOPIC” 这个topic对应的一个ConsumeQueue里去。 (也就是说,消息的完整信息还是写入到commitlog中了,只是offset偏移量没有写到对应topic的consumeQueue中,而是写入到了MQ内部特定topic的consumeQueue文件中了) 所以这就真相大白了,就能明白为什么消费者消费不到这条half消息了。

就是必须要half消息进入到RocketMQ内部的RMQ_SYS_TRANS_HALF_TOPIC的comsumeQueue文件中,此时就认为half消息写入成功了,然后就会返回成功消息给订单系统了。

其实RocketMQ后台有个定时任务,它会定时的去扫描RMQ_SYS_TRANS_HALF_TOPIC中的half消息,如果超过一定的时间,还是half消息,那么它会回调订单系统提供的接口,问你这个消息是rollback呢,还是commit呢。

之前我们说执行rollback请求后,MQ会删除这个half消息,你觉的MQ会真的删除该消息么?答案是不会真的删除的,因为RocketMQ都是顺序将消息写入磁盘文件的,所以在这里如果你执行rollback请求,它的本质是用一个op操作标记half消息的状态,这个op操作,就是RocketMQ中有一个OP_TOPIC,此时可以写一条rollback op记录到这个topic里,标记某个balf消息是被rollback了。

注:如果没有一直没有接受到rollback/commit请求,那么mq会主动调订单系统的接口,来询问这个half消息是需要rollback还是commit,这个最多回调15次,如果15次还没有一个准确的状态,那么mq自己就会把这个消息标记为rollback。

其实也很简单,如果订单系统执行了commit操作后,RocketMQ就会在OP_TOPIC中标记这个half消息为commit状态了。然后接着就需要将RMQ_SYS_TRANS_HALF_TOPIC中的half消息写入到OrderPaySuccessTopic的consumeQueue里去,然后我们的消费者系统,也就是积分系统就可以读取到这条消息了。

以上是关于RocketMQ事务机制的底层实现原理解析的主要内容,如果未能解决你的问题,请参考以下文章

RocketMQ 事务消息 原理及使用方法解析

Kafka设计解析- Exactly Once语义与事务机制原理

精华推荐 | 深入浅出RocketMQ原理及实战「底层原理挖掘系列」透彻剖析贯穿RocketMQ的存储系统的实现原理和持久化机制

精华推荐 | 深入浅出RocketMQ原理及实战「底层原理挖掘系列」透彻剖析贯穿RocketMQ的存储系统的实现原理和持久化机制

SpringSpring底层核心原理解析

RocketMQ原理解析-Remoting