关于RocketMQ详细了解

目录

1、核心组件

1.1、 基础概念

1.2、顺序消息原理

1.3、设计理念及性能

1.4、可靠性与持久化对比

2、RocketMQ 消费模式

2.1、广播模式

2.2、集群模式

3、基础架构

3.1、NameServer介绍

3.2、Broker介绍

3.2、存储文件简介

3.4、消费流程

3.5、消费负载均衡策略

4、数据持久化

4.1、刷盘策略

1、同步刷盘(Synchronous Flush)

2、异步刷盘(Asynchronous Flush)

4.2、刷盘策略的实现

5、broker数据同步

5.1、同步机制

5.2、核心目标

5.3、同步复制的核心流程

5.4、同步复制的可靠性保障

6、消费者故障处理


前言

  RocketMQ 是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ 的特点是纯JAVA实现。

更多关于RocketMQ的介绍,参考:MQ消息队列的深入研究-CSDN博客文章浏览阅读1.1k次,点赞21次,收藏24次。前言消息队列(Message Queue,简称 MQ)是一种用于在分布式系统中实现异步通信的技术。它提供了一个可靠的机制,可以在应用程序或服务之间传递消息,以提高系统的如下图所示:Apache Kafka、RabbitMQ、RocketMQ 和 ActiveMQ 是流行的消息队列解决方案,它们在架构设计、性能、特性和适用场景上各有不同。 https://blog.csdn.net/weixin_50055999/article/details/147952429?spm=1011.2415.3001.5331

架构图如下所示:

天然弊端

  RocketMQ 采用一个 consumer 绑定一个或者多个 Queue 模式,假如某个消费者服务器挂了,则会造成部分Queue消息堆积。

        而kafka中的分区会采用reblace机制,重新分配消费者。


1、核心组件

1.1、 基础概念


Producer:

        消息生产者,负责产生消息,一般由业务系统负责产生消息。


Producer Group:

        消息生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者。


Consumer:

        消息消费者,负责消费消息,一般是后台系统负责异步消费。


Consumer Group:

        消费者组,和生产者类似,消费同一类消息的多个 Consumer 实例组成一个消费者组。


Topic:

        主题,用于将消息按主题做划分,Producer将消息发往指定的Topic,Consumer订阅该Topic就可以收到这条消息。


Message:

        消息,每个message必须指定一个topic,Message 还有一个可选的 Tag 设置,以便消费端可以基于 Tag 进行过滤消息。


Tag:

        标签,子主题(二级分类)对topic的进一步细化,用于区分同一个主题下的不同业务的消息。


Broker:

        Broker是RocketMQ的核心模块,负责接收并存储消息,同时提供Push/Pull接口来将消息发送给Consumer。

        Broker同时提供消息查询的功能,可以通过MessageID和MessageKey来查询消息。Borker会将自己的Topic配置信息实时同步到NameServer。


Queue:

        Topic和Queue是1对多的关系,一个Topic下可以包含多个Queue,主要用于负载均衡,Queue数量设置建议不要比消费者数少。发送消息时,用户只指定Topic,Producer会根据Topic的路由信息选择具体发到哪个Queue上。Consumer订阅消息时,会根据负载均衡策略决定订阅哪些Queue的消息。


Offset:

        RocketMQ在存储消息时会为每个Topic下的每个Queue生成一个消息的索引文件,每个Queue都对应一个Offset记录当前Queue中消息条数。


NameServer:

        NameServer可以看作是RocketMQ的注册中心,它管理两部分数据:集群的Topic-Queue的路由配置;Broker的实时配置信息。其它模块通过Nameserv提供的接口获取最新的Topic配置和路由信息;各 NameServer 之间不会互相通信, 各 NameServer 都有完整的路由信息,即无状态。
Producer/Consumer :通过查询接口获取Topic对应的Broker的地址信息和Topic-Queue的路由配置


Broker :

         注册配置信息到NameServer, 实时更新Topic信息到NameServer

1.2、顺序消息原理

1、顺序消息支持

        RocketMQ 提供了严格的顺序消息处理能力,无论是在分发消息还是消费消息,都能够保证相同分组的消息按顺序处理。

2、顺序消息原理

1.消息队列:

        在RocketMQ中,一个Topic会分为多个消息队列(Queue)。消息的顺序是通过队列保证的。生产者在发送消息时,根据某种规则(如消息的key)将属于同一组的消息发送到同一个队列中。

如下图所示:

2.单线程消费:

        消费者从某个队列中按顺序拉取消息。为了保证顺序,该队列的消息通常会由消费者的同一线程处理。

3.消息发送策略:

        生产者可以通过选择某种消息发送策略,将需要严格顺序处理的消息发送到同一个Queue,这通常通过消息中的业务key进行hash计算,然后选择一个具体的Queue。

4.故障恢复:

        如果队列中的消息因为消费失败而需要重试,RocketMQ支持将消费失败的消息重新放回到队列的头部,从而保持顺序性。

1.3、设计理念及性能

  • RocketMQ

    • 顺序消息:支持严格顺序消息(全局顺序或分区顺序),通过 MessageQueue 和 MessageListener 实现。
    • 事务消息:支持分布式事务消息(半事务消息 + 回查机制),适合跨系统数据一致性(如订单扣款、库存更新)。
    • 延迟消息:支持 18 个固定延迟等级(如 1s、5s、10s 到 2h)。
    • 消息标签(Tag):通过 Tag 对消息分类,支持灵活的消费过滤。
  • Kafka

    • 分区顺序:仅保证单分区内的顺序性,需业务层维护全局顺序。
    • 无事务消息:原生不支持事务消息(Kafka 2.0+ 支持事务 API,但复杂度高)。
    • 延迟消息:需通过定时任务或外部组件实现。
  • RabbitMQ

    • 消息确认机制:支持手动/自动确认,但不支持事务消息。
    • 延迟消息:需通过插件(如 rabbitmq_delayed_message_exchange)实现。
    • 消息优先级:支持消息优先级队列。
  • ActiveMQ

    • JMS 标准:完全兼容 JMS 1.1,但性能较弱。
    • 事务支持:支持本地事务,但不支持跨系统分布式事务。

1.4、可靠性与持久化对比

  • RocketMQ

    • 同步双写:支持 Broker 间同步复制,确保数据不丢失。
    • 刷盘策略:异步刷盘(高性能)或同步刷盘(强一致性)。
    • 消息回溯:支持任意时间点的消息回溯(消费位点管理)。
  • Kafka

    • ISR 机制:通过副本同步队列(In-Sync Replicas)保障数据可靠性。
    • 持久化:消息持久化到磁盘,但依赖副本数和 acks 配置。
    • 消息回溯:需手动维护消费偏移量(offset)。
  • RabbitMQ

    • 持久化队列/消息:通过 durable 和 persistent 标志实现。
    • 镜像队列:主备节点同步,但性能开销较大。
  • ActiveMQ

    • KahaDB/KahaMQ:默认持久化存储,但性能较弱。
    • 主备模式:支持 Master-Slave 架构,但切换复杂。


2、RocketMQ 消费模式

2.1、广播模式

   一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每一个Consumer都消费一次。(消费者和queue为强绑定

//设置广播模式       
consumer.setMessageModel(MessageModel.BROADCASTING);

2.2、集群模式

一个Consumer Group中的所有Consumer平均分摊消费消息(组内负载均衡)。

//设置集群模式,也就是负载均衡模式
consumer.setMessageModel(MessageModel.CLUSTERING);

3、基础架构

3.1、NameServer介绍


   rocketMq使用轻量级的NameServer服务进行服务的协调和治理工作,NameServer多节点部署时相互独立互不干扰。

        每一个rocketMq服务节点(broker节点)启动时都会遍历配置的NameServer列表并建立长链接,broker节点每30秒向NameServer发送一次心跳信息、NameServer每10秒会检查一次连接的broker是否存活。

        消费者和生产者会随机选择一个NameServer建立长连接,通过定期轮训更新的方式获取最新的服务信息。

架构简图如下:

NameServer:

        启动,监听端口,等待producer,consumer,broker连接上来

Broker:

        启动,与nameserver保持长链接,定期向nameserver发送心跳信息,包含broker的ip,端口,当前broker上topic的信息

producer:

        启动,随机选择一个NameServer建立长连接,拿到broker的信息,然后就可以给broker发送消息了

consumer:

        启动,随机选择一个NameServer建立长连接,拿到broker的信息,然后就可以建立通道,消费消息

3.2、Broker介绍

        RocketMQ 存储用的是本地文件存储系统,将所有topic的消息全部写入同一个文件中(commit log),这样保证了IO写入的绝对顺序性,最大限度利用IO系统顺序读写带来的优势提升写入速度。

  由于消息混合存储在一起,需要将每个消费者组消费topic最后的偏移量记录下来。这个文件就是consumer queue(索引文件)。所以消息在写入commit log 文件的同时还需将偏移量信息写入consumer queue文件。在索引文件中会记录消息的物理位置、偏移量offse,消息size等,消费者消费时根据上述信息就可以从commit log文件中快速找到消息信息。

Broker 存储结构如下:

3.2、存储文件简介


1、Commit log:

        消息存储文件,rocket Mq会对commit log文件进行分割(默认大小1GB),新文件以消息最后一条消息的偏移量命名。(比如 00000000000000000000 代表了第一个文件,第二个文件名就是 00000000001073741824,表明起始偏移量为 1073741824)。


2、Consumer queue:

        消息消费队列(也是个文件),可以根据消费者数量设置多个,一个Topic 下的某个 Queue,每个文件约 5.72M,由 30w 条数据组成;ConsumeQueue 存储的条目是固定大小,只会存储 8 字节的 commitlog 物理偏移量,4 字节的消息长度和 8 字节 Tag 的哈希值,固定 20 字节;消费者是先从 ConsumeQueue 来得到消息真实的物理地址,然后再去 CommitLog 获取消息。


3、IndexFile:

索引文件,是额外提供查找消息的手段,通过 Key 或者时间区间来查询对应的消息

3.4、消费流程

        Producer 使用轮询的方式分别向每个 Queue 中发送消息。

  Consumer 启动的时候会在 Topic,Consumer group消费者组 维度发生负载均衡,为每个客户端分配需要处理的 Queue。

        负载均衡过程中每个客户端都获取到全部的的 ConsumerID 和所有 Queue 并进行排序,每个客户端使用相同负责均衡算法,例如平均分配的算法,这样每个客户端都会计算出自己需要消费那些 Queue,每当 Consumer 增加或减少就会触发负载均衡,所以我们可以通过 RocketMQ 负载均衡机制实现动态扩容,提升客户端收发消息能力。

        客户端负责均衡为客户端分配好 Queue 后,客户端会不断向 Broker 拉取消息,在客户端进行消费。

注意:

        可以一直增加客户端的数量提升消费能力吗?当然不可以,因为 Queue 数量有限,客户端数量一旦达到 Queue 数量,再扩容新节点无法提升消费能力,因为会有节点分配不到 Queue 而无法消费。

这点类似于kafka消息积压:kafka消费的模式及消息积压处理方案-CSDN博客文章浏览阅读703次,点赞15次,收藏18次。 Kafka消费积压(Consumer Lag)是指消费者处理消息的速度跟不上生产者发送消息的速度,导致消息在Kafka主题中堆积。1. 如果是Kafka消费能力不足,则可以考虑增加 topic 的 partition 的个数(提高kafka的并行度),同时提升消费者组的消费者数量,消费数 = 分区数 (二者缺一不可)2. 若是下游数据处理不及时,则提高每批次拉取的数量。批次拉取数量过少(拉取数据/处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压。 https://blog.csdn.net/weixin_50055999/article/details/148747641?spm=1011.2124.3001.6209

3.5、消费负载均衡策略

  topic 在创建之处可以设置 comsumer queue数量。而 comsumer 在启动时会和comsumer queue绑定,这个绑定策略是咋样的?

如下图所示:

1、默认策略:


        queue 个数大于 Consumer个数, 那么 Consumer 会平均分配 queue,不够平均,会根据clientId排序来拿取余数。


        queue个数小于Consumer个数,那么会有Consumer闲置,就是浪费掉了,其余Consumer平均分配到queue。


2、一致性hash算法

        就近元则,离的近的消费。每个消费者依次消费一个queue,环状。


4、数据持久化

         刷盘策略 是消息持久化的核心机制,决定了消息从内存写入磁盘的方式和时机。它直接影响系统的 可靠性性能 和 可用性

如下图所示:

4.1、刷盘策略

RocketMQ 提供了两种主要的刷盘策略:同步刷盘 和 异步刷盘

1、同步刷盘(Synchronous Flush)

  • 机制
    • 生产者发送消息后,Broker 将消息写入内存缓冲区(PageCache),然后 立即调用文件刷盘操作,等待磁盘 IO 完成后再返回生产者结果。
    • 刷盘操作由 主线程(HandleFlushThread)负责,确保消息落盘后才确认消息写入成功。
  • 优点
    • 强一致性:消息写入磁盘后才返回成功,确保消息不会丢失(即使 Broker 崩溃)。
    • 适用于对数据可靠性要求极高的场景(如金融交易、支付系统)。
  • 缺点
    • 性能较低:由于需要等待磁盘 IO 完成,吞吐量受限,延迟较高。
    • 依赖磁盘 IO 性能,可能成为性能瓶颈。
  • 配置示例
# 在 broker 配置文件中设置
flushDiskType=SYNC_FLUSH

2、异步刷盘(Asynchronous Flush)

  • 机制
    • 生产者发送消息后,Broker 将消息写入内存缓冲区(PageCache),不等待磁盘 IO 完成,直接返回生产者成功。
    • 后台有一个独立的 刷盘线程(FlushRealTimeService),定期(默认 500ms)或当内存缓冲区满时,将消息刷入磁盘。
  • 优点
    • 高性能:无需等待磁盘 IO,吞吐量高,延迟低。
    • 适用于高并发、低延迟的场景(如日志收集、事件流处理)。
  • 缺点
    • 存在消息丢失风险:如果 Broker 崩溃或宕机,未刷盘的消息可能丢失(通常最多丢失 500ms 的数据)。
  • 配置示例
# 在 broker 配置文件中设置
flushDiskType=ASYNC_FLUSH

4.2、刷盘策略的实现

如下图所示:

1. 内存缓冲区(PageCache)

  • RocketMQ 使用操作系统的 PageCache 机制缓存消息数据,减少直接磁盘 IO 的开销。
  • 当消息写入 PageCache 后,操作系统会异步将数据刷入磁盘(具体时机由操作系统管理)。

2. 刷盘线程(FlushRealTimeService)

  • 异步刷盘依赖后台线程 FlushRealTimeService,它会:
    • 每隔 500ms 检查内存缓冲区。
    • 如果缓冲区数据量超过阈值(默认 1GB),立即触发刷盘。
    • 如果缓冲区未满,按固定间隔刷盘。

3. 刷盘频率与性能

  • 同步刷盘:每次写入都触发刷盘,性能受限于磁盘 IO。
  • 异步刷盘:通过批量刷盘降低 IO 频率,性能显著高于同步刷盘。

5、broker数据同步

5.1、同步机制

        RocketMQ 的同步复制机制通过 主从架构 + 同步双写 实现数据强一致性,可靠性和高可用性的核心功能之一,确保即使主 Broker 宕机,数据也不会丢失。

其核心流程如下:

  1. Master 写入消息并持久化。
  2. 同步发送消息到 Slave 并等待 ACK。
  3. 收到 ACK 后返回生产者成功响应。

如下图所示:

5.2、核心目标

  1. 数据不丢失:主 Broker 写入消息后,必须确保从 Broker 同步完成写入。
  2. 高可用性主 Broker 宕机时,从 Broker 可快速接管服务。
  3. 强一致性:主从 Broker 的消息完全一致,避免数据差异。

5.3、同步复制的核心流程

  1. 消息写入 Master

    • 生产者发送消息到 Master Broker。
    • Master 将消息写入内存缓冲区(PageCache)并持久化到本地磁盘(根据刷盘策略,可能是同步或异步)。
    • 如果配置为 同步刷盘,Master 会等待磁盘写入完成后再继续下一步。
  2. 消息同步到 Slave

    • Master 将消息通过 Remoting 模块 发送给对应的 Slave Broker。
    • Slave 接收消息后,同样写入内存缓冲区并持久化到本地磁盘。
    • 如果配置为 同步复制,Master 会等待 Slave 返回写入成功的确认(ACK)。
  3. 事务提交与响应

    • 当 Master 收到 Slave 的 ACK 后,才向生产者返回写入成功的响应。
    • 如果 Slave 未在超时时间内返回 ACK,Master 会重试同步,直到成功或放弃(具体行为由配置决定)。

5.4、同步复制的可靠性保障

1. 数据一致性校验

  • 同步复制 保证主从 Broker 的 CommitLog 内容完全一致。
  • 如果从 Broker 宕机,重启后会从 Master 重新拉取缺失的消息进行同步。

2. 宕机恢复机制

  • 主 Broker 宕机:从 Broker 会接管服务,但需人工或自动切换为主角色(RocketMQ 原生不支持自动切换,需依赖外部工具如 Dledger)。
  • 从 Broker 宕机:主 Broker 会持续重试同步,直到从 Broker 恢复。

3. 网络异常处理

  • 超时重试:Master 会重试发送消息到 Slave,直到成功或达到最大重试次数。
  • 断线重连:网络中断后,HAService 会自动尝试重新连接 Slave。

优势

  • 数据不丢失,可靠性高。
  • 主从无缝切换,保障服务连续性。

注意事项

  • 性能开销较大,需合理配置刷盘策略和同步超时时间。
  • 不支持自动故障转移,需结合 Dledger 或外部工具实现。


6、消费者故障处理

1. 消费者绑定 Queue

  • 机制:RocketMQ 的消费者(Consumer)以 Consumer Group 为单位订阅 Topic,并绑定到一个或多个 MessageQueue(队列)。
  • 问题:如果某个消费者服务器挂掉,它负责的 Queue 会进入 “空闲”状态,消息无法被消费,导致 消息堆积
  • 原因
    • RocketMQ 的消费者与 Queue 是 强绑定关系,消费者宕机后,Queue 无法自动转移到其他消费者。
    • 除非人工干预或重启消费者,否则消息会持续堆积。

2. 解决方案

  • 手动恢复:重启宕机的消费者或调整消费者组内的消费者数量。
  • 负载均衡策略:通过合理配置消费者组内的消费者数量,避免单点故障。
  • 监控告警:实时监控消费者状态,及时发现并处理故障。


总结

  1. 需要分布式事务和严格顺序:优先选择 RocketMQ
  2. 高吞吐流处理或日志聚合:选择 Kafka
  3. 复杂路由或多协议支持:选择 RabbitMQ
  4. 传统 JMS 场景或小规模系统:选择 ActiveMQ

参考文章:

1、RocketMQ深入解析:消息传递与存储优化-CSDN博客文章浏览阅读3.5w次,点赞42次,收藏343次。RocketMQ 详解1. 基础概念2.RocketMQ 消费模式2.1 广播模式2.2 集群模式3. 基础架构3.1 Broker 的存储结构3.2 存储文件简介3.3 Consumer 端的负载均衡机制3.4 消息刷盘机制3.5 Mmap + pageCache3.5.1 传统IO 和 Mmap3.5.2 pageCache3.5.3 预映射机制 + 文件预热机制3.6 push/pull/pop3.7 Topic 分片3.8 查漏补缺3.8.1 消息的全局顺序和局部顺序3.8.2 零拷贝(Zero-c_rocketmq https://blog.csdn.net/weixin_44981707/article/details/124138939?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522a4662e4730b3536bcc3476e459c0536e%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=a4662e4730b3536bcc3476e459c0536e&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-124138939-null-null.142^v102^control&utm_term=rocketmq%E8%AF%A6%E8%A7%A3&spm=1018.2226.3001.4187

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值