RocketMQ-架构与设计
作者:mmseoamin日期:2024-02-22

RocketMQ架构与设计

  • 一、简介
  • 二、框架概述
    • 1.设计特点
    • 三、架构图
      • 1.Producer
      • 2.Consumer
      • 3.NameServer
      • 4.BrokerServer
      • 四、基本特性
        • 1.消息顺序性
          • 1.1 全局顺序
          • 1.2 分区顺序
          • 2.消息回溯
          • 3.消息重投
          • 4.消息重试
          • 5.延迟队列(定时消息)
          • 6.重试队列
          • 7.死信队列
          • 8.消息语义
          • 9.事务消息
          • 10.消息过滤
          • 11.流量控制
          • 五、设计原理
            • 1.消息重试
            • 2.延迟队列(定时消息)
            • 3.事务消息
            • 4.消费订阅模式
              • 4.1 广播模式
              • 4.2 集群模式
              • 总结
              • 参考链接

                一、简介

                RocketMQ是阿里巴巴开发的纯Java的分布式、队列模型的开源消息中间件,其架构简单、业务场景丰富,支持分布式事务、是一款金融级别可靠业务消息中间件。

                二、框架概述

                1.设计特点

                • 架构简单、不依赖外部组件
                • 支持事务消息
                • 支持特定固定间隔的延迟队列
                • 支持上千消息主题

                  三、架构图

                  Apache RocketMQ部署架构图如下:

                  RocketMQ-架构与设计,在这里插入图片描述,第1张

                  1.Producer

                  消息发布者向Broker集群进行消息投递,支持分布式集群方式部署。

                  2.Consumer

                  消息消费者从Broker集群进行消息消费;支持push和pull两种模式对消息消费;支持集群和广播方式进行消费。

                  3.NameServer

                  消息主题管理中心,支持Broker的动态注册和发现;支持集群部署,但各个实例间互相不进行通信;每个实例保存完整的Broker路由信息;

                  4.BrokerServer

                  负责消息的存储、投递和查询;支持集群部署;Broker采用主从部署,一个Master对应一个Slave,采用同步复制或者异步复制;管理客户端和维护Consumer的Topic订阅信息;

                  四、基本特性

                  1.消息顺序性

                  1.1 全局顺序

                  指定Topic只使用一个队列,单个生产者和单个消费者。性能要求不高。

                  1.2 分区顺序

                  指定Topic根据sharding key进行分区,可以保证分区内数据顺序性。性能比较高。

                  2.消息回溯

                  支持按照时间回溯消息,时间维度精确到毫秒

                  3.消息重投

                  消息投递失败,会进行重新投递

                  4.消息重试

                  消费失败之后,会利用延迟队列进行重试,令消息再消费一次。

                  5.延迟队列(定时消息)

                  RocketMQ支持固定延迟时间的延迟队列,总共18个延迟等级。延迟消息先保存到Broker的SCHEDULE_TOPIC_XXXX中,等到了特定时间会投递到真正的Topic中。

                  6.重试队列

                  重试队列是指一个与原消息队列相关的一个队列,此队列用于存放消费失败的消息。

                  7.死信队列

                  重试次数达到一定次数后,会将消息投递此队列。

                  8.消息语义

                  RocketMQ支持At least Once(至少一次),消息至少被写入一次。producer保存发送失败消息再次发送,服务端不保证消息去重。

                  9.事务消息

                  事务消息是指应用本地事务和发送消息操作定义到全局事务中,要么同时成功,要没同时失败。RocketMQ事务消息提供了分布事务能力,通过事务消息达到分布式事务的最终一致性。

                  10.消息过滤

                  支持根据Tag或者自定义属性对消息进行过滤。过滤功能由Broker端实现,减少无用消息到达Consumer端。

                  11.流量控制

                  如果broker处理能力达到瓶颈会对生产者消息投递进行限流处理;如果消费能力达到瓶颈会对消费者拉取频率进行限流处理。

                  五、设计原理

                  1.消息重试

                  RocketMQ会为每个消费组创建重试队列和死信队列;其中重试队列名称格式为RETRY+consumerGroup,死信队列名称格式为DLQ+consumerGroup。

                  • 重试投递延迟随着次数逐步增大,与延迟队列支持的延迟时间等级一致
                  • Broker先将重试消息保存到延迟队列中,然后在对应Delay时候后重新投递到重试队列中
                  • 如果超过最大重试次数,则会保存到死信队列中

                    2.延迟队列(定时消息)

                    Broker中有一系列名为SCHEDULE_TOPIC_XXXX的延迟消息暂存队列,共有18个延迟消费队列,每个消费队列中的消息延迟时间一致。整体流程如下:

                    • 延迟消息到达Broker后,会将消息的topic和queueId改写,然后写入commitlog
                    • ReputMessageServie线程异步将CommitLog中消息按照延迟的时间保存到对应的延迟消息暂存队列
                    • 每个队列有单独的ScheduleMessageService定时投递任务,拉取消息判断是否到期,然后将消息topic和queueId恢复,写入commitLog进行重新投递

                      RocketMQ-架构与设计,在这里插入图片描述,第2张

                      3.事务消息

                      Rocketmq事务消息是指Producer端发送事件和本地事务事件,同时成功或者同时失败。事务消息会被投递到RMQ_SYS_TRANS_HALF_TOPIC,提交会将消息投递到原Topic,回滚则会删除消息。

                      整体流程如下:

                      • 3.1 生产者发送一个半消息给Broker,此时消息对消费者不可见
                      • 3.2 Broker返回后,生产者执行本地事务
                      • 3.3 根据本地事务执行情况,执行消息Commit或着Rollback
                      • 3.4 如果broker长时间没有收到事务的提交或者回滚,会向生产者发送查询请求
                      • 3.5 生产者提供接口,执行查询本地事务的执行状态

                        RocketMQ-架构与设计,在这里插入图片描述,第3张

                        4.消费订阅模式

                        4.1 广播模式

                        一个消息的消费队列被同一个消费组中的所有消费者消费;一个消费队列会把每条消息推送给消费组所有的消费者。

                        4.2 集群模式

                        一个消息的消费队列只被同一个消费组中的一个消费者消费;一个消费队列会把消息推送给消费组中的一个消费者。

                        • 如果消费组中消费者数量小于消费队列数量,可以增加消费者数量来提高消费能力
                        • 如果消费组中消费者数量大于消费队列数量,则多余的消费者无法消费

                          RocketMQ-架构与设计,第4张

                          总结

                          RocketMQ是一个分布式消息队列,经过阿里巴巴大规模实际应用检验。RocketMQ除了基本的队列功能,还支持事务消息、消息过滤、流量控制等功能特性。由于将所有消息主题保存到同一个文件,所以可以支持大量消息主题,topic从几十到几百,吞吐量只有小幅度下降,所以特别适合消息队列的应用场景(topic众多,但是每个topic消息量比较小)。


                          参考链接

                          1.Apache RocketMQ

                          2.GitHub RocketMQ中文文档

                          3.Apache RocketMQ开发者指南