RocketMQ 的负载均衡(Load Balancing)机制是其高可用、高吞吐能力的核心组成部分,主要体现在 生产者发送消息的负载均衡消费者消费消息的负载均衡 两个层面。两者均基于 Topic 的 Queue 分片模型 实现,但策略和目标不同。

下面从原理、实现机制、策略类型、代码逻辑等方面详细阐述 RocketMQ 的负载均衡实现。

核心基础

核心为 Topic 与 Queue 模型,在 RocketMQ 中

  • 一个 Topic 被划分为多个 MessageQueue(简称 Queue)。

  • 每个 Queue 是有序、不可分割的最小存储和消费单元。

  • Queue 分布在多个 Broker 上(主从架构),实现数据分片和并行处理。

image-20251011233016362

生产者负载均衡

将消息均匀发送到 Topic 的所有 Queue,避免热点 Queue,提升吞吐。

轮询策略(默认)

  • RocketMQ Producer 内部维护一个 index 计数器。

  • 每次发送消息时,index++,然后 index % queueTotal 选择 Queue。

  • 保证消息在所有 Queue 间均匀轮询

1
2
3
4
// DefaultMQProducer 内部逻辑简化版
int nextIndex = this.sendWhichQueue.getAndIncrement();
int queueIndex = Math.abs(nextIndex) % queueList.size();
MessageQueue selectedQueue = queueList.get(queueIndex);

自定义策略

当需要顺序消息按业务 Key 路由时,可自定义选择器:MessageQueueSelector

1
2
3
4
5
producer.send(msg, (mqs, msg, arg) -> {
String key = (String) arg;
int idx = key.hashCode() % mqs.size();
return mqs.get(idx);
}, "orderId123");

此时负载均衡由业务逻辑控制,不再轮询

故障规避

  • Producer 会定期从 NameServer 拉取 Topic 路由信息(默认 30 秒)。

  • 如果某个 Broker 不可用,其上的 Queue 会被自动剔除,后续消息只发往健康 Queue。

  • 支持 sendLatencyFaultEnable(延迟容错):若某 Broker 发送慢,会临时规避一段时间。

消费者负载均衡

将 Topic 的所有 Queue 均匀分配给当前 Consumer Group 中的多个 Consumer 实例,实现并行消费。

核心机制:Rebalance(重平衡)

触发时机

  • Consumer 启动时

  • 新 Consumer 加入或退出 Group

  • Topic 的 Queue 数量变化(如扩容)

  • 定时任务(默认每 20 秒)

负载均衡策略

RocketMQ 提供多种分配策略,默认是 平均分配(AllocateMessageQueueAveragely)

策略 说明
AllocateMessageQueueAveragely(默认) 平均分配,尽量均分 Queue
AllocateMessageQueueAveragelyByCircle 轮询分配(适合 Queue 数 < Consumer 数)
AllocateMessageQueueByMachineRoom 按机房分配(需配置)
AllocateMessageQueueConsistentHash 一致性哈希(减少重平衡抖动)
AllocateMessageQueueByConfig 按配置分配(静态)

平均分配(4 Queues, 2 Consumers):

  • Consumer-1: Queue-0, Queue-1
  • Consumer-2: Queue-2, Queue-3

轮询分配(3 Queues, 2 Consumers):

  • Consumer-1: Queue-0, Queue-2

  • Consumer-2: Queue-1

分配过程

  1. Consumer 从 NameServer 获取 Topic 所有 Queue 列表。

  2. 获取当前 Consumer Group 下所有在线 Consumer 实例(通过心跳注册到 Broker)。

  3. 对 Queue 列表和 Consumer 列表排序(保证所有实例计算结果一致)。

  4. 应用分配策略,计算本实例应消费的 Queue 子集。

  5. 更新本地消费队列,并启动/停止对应 Queue 的拉取任务。

  • 顺序消费时,一个 Queue 只能被一个 Consumer 消费(加分布式锁)。

  • 负载均衡仍按上述策略分配,但消费线程为单线程。

两种模式

  1. 集群模式(CLUSTERING)

    • Queue 在 Consumer Group 内共享,每条消息只被一个 Consumer 消费。
    • 适用于任务分发、削峰填谷等场景。
    • 负载均衡在此模式下生效。
  2. 广播模式(BROADCASTING)

    • 每个 Consumer 都消费所有 Queue 的全部消息

    • 无负载均衡概念,每个实例独立消费全量数据。

    • 适用于缓存更新、配置同步等场景。

负载均衡的可靠性保障

  1. 心跳机制

    • Consumer 每 30 秒向所有 Broker 发送心跳,注册自身信息。

    • Broker 维护 Consumer Group 的在线列表,用于 Rebalance。

  2. 重平衡幂等性

    • Rebalance 过程是幂等的,多次执行结果一致。

    • 拉取消息时基于 PullOffset,避免重复或丢失。

  3. 故障转移

    • 若 Consumer 宕机,其他实例在下一次 Rebalance(20 秒内)接管其 Queue。

    • 消费进度(Consumer Offset)持久化在 Broker(集群模式)或本地(广播模式)。