RocketMQNotes

第 18 章:Controller 与高可用

zjc 于 2026-01-18 发布

这是《RocketMQ 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Controller 模式是 RocketMQ 5.x 高可用架构的重要演进方向,用独立的控制器参与副本选主、角色切换和副本一致性裁决。相比传统手工主从或基于内嵌共识组件的模式,它把“谁能当主”这件事从人工操作和节点自判中抽离出来。

18.1 传统主从的问题

传统主从部署中,如果主节点故障:

master down
  -> ops detects
  -> promote replica
  -> update route
  -> client reconnect

风险:

  1. 人工介入时间不可控;
  2. 提升哪个副本需要判断位点;
  3. 老主恢复后可能出现双主;
  4. 切换期间写入不可用;
  5. 消费位点可能超过数据位点。

自动高可用要解决的不只是“切换快”,还包括“怎么选最安全的副本”和“如何避免脑裂”。

18.2 Controller 的职责

Controller 常见职责:

职责 说明
副本选举 选择可提升为主 的副本
角色裁决 决定 master / replica
epoch 管理 通过递增任期隔离旧主
复制状态 跟踪副本同步进度
路由联动 与 NameServer 协同更新
异常恢复 处理节点重新上线

不同小版本的功能范围可能变化,部署前应以当前官方文档和配置说明为准。

18.3 选主流程

示意流程:

master heartbeat timeout
  -> controller detects failure
  -> select replica with latest durable state
  -> verify replica synchronization
  -> increase epoch
  -> promote replica to master
  -> notify brokers and nameservers
  -> old master rejoins as replica

关键判断是副本位点,而不是简单选择编号最小的节点。

18.4 Epoch 与 fencing

epoch 或 term 用于隔离旧 leader:

epoch 10 old master
epoch 11 new master

当旧主恢复后:

  1. 发现已有更高 epoch;
  2. 停止接受写入;
  3. 对齐新主数据;
  4. 转为副本;
  5. 不再以旧身份返回成功。

如果缺乏有效 fencing,客户端可能仍连接旧主,造成双写或数据回退。

18.5 部署形态

常见部署:

  1. Controller 独立部署多节点;
  2. Controller 与 Broker 混合部署;
  3. 云托管平台托管控制器;
  4. Controller 使用 Raft 或其他共识机制维持自身可用性。

建议:

  1. Controller 至少 3 个投票节点;
  2. 与 Broker 分故障域部署;
  3. 使用低延迟稳定网络;
  4. 明确仲裁节点分布;
  5. 不与高负载存储盘混抢资源;
  6. 保留运维命令和配置审计。

18.6 故障场景

故障 行为目标
主 Broker 宕机 选举同步副本
副本宕机 主继续服务,副本不足时告警
Controller 宕机 多数派仍可用
网络分区 多数派继续,少数派不可提升
NameServer 故障 已有路由可服务,新发现受影响
机房故障 跨可用区副本参与恢复

注意:Controller 保证的是副本编排层面的高可用,不替代备份、监控和容量规划。

18.7 客户端影响

切换期间客户端可能遇到:

  1. 连接断开;
  2. 发送超时;
  3. 路由更新延迟;
  4. 队列重分配;
  5. 消费重平衡;
  6. 重试增加。

应用应配置:

send timeout
retry times
backoff
consume timeout
circuit breaker
local compensation

不要在发送失败时无退避地猛打重试。

18.8 监控指标

controller_leader_exists
controller_epoch
controller_voting_quorum_size
broker_role
broker_sync_state
replica_sync_offset_diff
master_switch_total
master_switch_duration_ms
broker_offline_total

告警:

  1. 无 Controller leader;
  2. 仲裁节点不可用;
  3. 副本长期未同步;
  4. 频繁切换;
  5. epoch 异常变化;
  6. 副本数量低于预期。

18.9 演练清单

  1. 重启主 Broker;
  2. 重启副本;
  3. 关闭一个 Controller;
  4. 关闭多数 Controller;
  5. 模拟网络分区;
  6. 磁盘满;
  7. NameServer 不可用;
  8. 客户端重连;
  9. 旧主恢复;
  10. 跨可用区断连。

演练要验证数据位点、消息完整性、路由状态和业务对账结果,而不只是看服务是否恢复。

本章小结

Controller 模式把自动选主、角色裁决和 fencing 引入 RocketMQ 高可用体系,降低人工恢复成本和脑裂风险。高可用能力依赖仲裁拓扑、副本同步、NameServer 路由和客户端重试策略共同工作。生产上必须监控 epoch、副本差距和切换次数,并通过真实故障演练验证。

思考题

  1. 自动选主为什么要选择位点最新的副本?
  2. epoch 如何防止旧主继续写入?
  3. Controller 集群为什么需要奇数投票节点?
  4. NameServer 故障时客户端为什么可能仍能发送?
  5. 为什么副本长期不同步比一次切主更危险?