RocketMQ

RocketMQ

Scroll Down

RocketMQ是阿里巴巴在2012年开源的消息队列产品,现已成为Apache顶级项目,是一个性能、稳定性和可靠性都非常不错的消息队列,它在响应延时方面做了很多优化,比起基于异步批量处理的Kafka,它在延时响应方面的表现会明显占优

消息模型

RocketMQ的消息模型是标准的发布-订阅模型,发布者将消息推送给主题,消费者订阅主题并消费消息,每个主题会由多个队列组成,每条消息会被以一定策略投递到主题下的某个队列中供多消费者并行消费,消息的顺序只能保证到队列的粒度,在主题粒度上无法保证有序

在RocketMQ的消息模型中,订阅者通过消费组的概念来进行分组,每个消费组都会消费主题中一份完整的消息,不同消费组之间消费进度互补影响,每个消费组中可包含多个消费者,每个消费组之中的多个消费者之间是竞争关系

由于Topic中的消息需要被不同的消费组消费,因此消费完的信息不能立即删除,RocketMQ会为每个消费组在每个队列上维护一个消费位置,消费位置前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消费消息,消费位置就会指向下一条消息

具体消息模型如下图所示:

image.png

物理架构

物理架构图

image.png

一个完整的RocketMQ集群大概由以下五部分组成:

  • NameServer Cluster

NameServer是一个几乎无状态的节点,类似于一个注册中心。每个Broker都会定时将Topic信息注册到NameServer上,Producer和Consumer都会随机选择一个NameSever节点建立长连接获取路由信息,然后通过获取到的路由信息与相应提供Topic服务的Broker建立长连接

  • Broker Cluster

Broker是真正维护主题队列及队列中消息的节点,Broker分为Master节点和Slave节点,Master节点和Slave节点是一对多的关系,一组主从Broker需要定义相同的BrokerName,使用不同的BrokerId区分,BrokerId为0表示Master,非0表示Slave

  • Producer Cluster

消息的生产者,生产者之间会用Producer Group的形式分组

  • Consumer Cluster

消息的消费者,消费者之间会用Consumer Group的形式分组

  • Console (可选)

RocketMQ的管理界面,方便可视化运维操作及监控,并非必须部署

API调用

Producer常用的发送方式有同步发送,异步发送,单向发送(不确认),还有事务消息,具体的Example代码在RocketMQ官方文档中已经非常详尽了,本文着重介绍一下RocketMQ中事务消息的实现方式

RocketMQ的Producer在事务消息模式下发送给Broker的消息共有以下三种状态

  • UNKNOWN
  • ROLLBACK_MESSAGE
  • COMMIT_MESSAGE

而事务消息的发送又分为三个阶段

  1. 向Broker发送一个半消息,消息的状态为UNKNOWN,该状态下的消息对Consumer不可见
  2. 触发Producer上注册的TransactionListener中执行本地事务的方法executeLocalTransaction,该方法会返回一个Message的状态
  3. 将TransactionListener中执行完本地事务后executeLocalTransaction 方法返回的状态发送给Broker,若为COMMIT_MESSAGE则消息对Consumer可见,若为ROLLBACK_MESSAGE则销毁该消息

事务反查流程图

image.png

在该流程中若第三步的状态码返回失败或因其他原因Broker一直无法收到状态码,Broker会去对应的Producer中反查这些半消息的状态,Producer端通过实现注册在Producer上的TransactionListener中checkLocalTransaction方法来为Broker提供反查的结果