RocketMQ消息流转和有序性
2020-11-02 本文已影响0人
雁阵惊寒_zhn
RocketMQ架构
RocketMQ架构图——截图自Apache RocketMQ官网NameServer Cluster
提供轻量级的发现和路由服务。每一个NameServer都会记录整个集群的全部路由信息,提供读写服务和快速的扩容服务。
Broker Cluster
Broker用于存储消息,提供TOPIC和QUEUE的实现机制。一个TOPIC可以提供多个QUEUE进行消息的接受和发送。
Producer Cluster
多个Producer组成一个Producer Group,一个Producer向某个TOPIC中的QUEUE发送消息。
Consumer Cluster
多个Consumer组成一个Consumer Group,一个Consumer Group会消费一个TOPIC中的消息。
RocketMQ消息流转
如下图:
消息流转流程图——图片摘自网络
- Producer发送消息,首先会向Server发送一条半消息(half/prepare message)。
- Server将半消息持久化后,会向Producer发送确认半消息成功的回复。
- Producer执行本地的事务逻辑。
- 根据本地事务执行的情况,Producer会向Server发送二次确认消息,回滚消息或提交消息。
4.1. 如果Server收到的是回滚消息,删除之前持久化的半消息,Consumer不会接受到这条消息。
4.2. 如果Server收到的是提交消息,会将半消息标记为可投递,Consumer可以收到这条消息。
上面所述是一个正常的消息投递和接受过程,RocketMQ消息发送使用的是类似二次提交的策略(2PC可参考分布式一致性——2PC和3PC)。
下面介绍容错机制,当Producer发送出现错误时,如何处理。
- 首先要确定第一次发送半消息出现错误,不会产生大影响,只需要再次发送即可。如果因为网络中断或者应用重启导致第二次发送确认消息失败(上面的步骤4),最终消息未能到达Server,经过一段时间后,Server会对这条半消息发起消息回查,即向Producer询问这条半消息的情况。
- Producer收到消息回查请求后,会检查对应消息的本地事务执行的状态和结果。
- 根据检查的本地事务执行的结果,再次发送提交或者回滚消息,Server根据消息类型执行上面步骤4描述的操作对半消息进行处理。
RocketMQ消息有序性
如下图,对于指定的一个TOPIC,Producer根据Sharding Key的逻辑(Producer中就是MessageQueueSelector接口实现的select方法)进行分区,把相同分区的消息投递到同一个Broker的QUEUE中。Broker中每一个QUEUE内的消息都是按照FIFO顺序排序的。Consumer消费时也按照FIFO顺序进行消费,一个QUEUE中的消息只发送给一个Consumer。从而,在Producer,Broker和Consumer三个组件层面保证了消息的有序性。