这是《RocketMQ 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Controller 模式是 RocketMQ 5.x 高可用架构的重要演进方向,用独立的控制器参与副本选主、角色切换和副本一致性裁决。相比传统手工主从或基于内嵌共识组件的模式,它把“谁能当主”这件事从人工操作和节点自判中抽离出来。
18.1 传统主从的问题
传统主从部署中,如果主节点故障:
master down
-> ops detects
-> promote replica
-> update route
-> client reconnect
风险:
- 人工介入时间不可控;
- 提升哪个副本需要判断位点;
- 老主恢复后可能出现双主;
- 切换期间写入不可用;
- 消费位点可能超过数据位点。
自动高可用要解决的不只是“切换快”,还包括“怎么选最安全的副本”和“如何避免脑裂”。
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
当旧主恢复后:
- 发现已有更高 epoch;
- 停止接受写入;
- 对齐新主数据;
- 转为副本;
- 不再以旧身份返回成功。
如果缺乏有效 fencing,客户端可能仍连接旧主,造成双写或数据回退。
18.5 部署形态
常见部署:
- Controller 独立部署多节点;
- Controller 与 Broker 混合部署;
- 云托管平台托管控制器;
- Controller 使用 Raft 或其他共识机制维持自身可用性。
建议:
- Controller 至少 3 个投票节点;
- 与 Broker 分故障域部署;
- 使用低延迟稳定网络;
- 明确仲裁节点分布;
- 不与高负载存储盘混抢资源;
- 保留运维命令和配置审计。
18.6 故障场景
| 故障 | 行为目标 |
|---|---|
| 主 Broker 宕机 | 选举同步副本 |
| 副本宕机 | 主继续服务,副本不足时告警 |
| Controller 宕机 | 多数派仍可用 |
| 网络分区 | 多数派继续,少数派不可提升 |
| NameServer 故障 | 已有路由可服务,新发现受影响 |
| 机房故障 | 跨可用区副本参与恢复 |
注意:Controller 保证的是副本编排层面的高可用,不替代备份、监控和容量规划。
18.7 客户端影响
切换期间客户端可能遇到:
- 连接断开;
- 发送超时;
- 路由更新延迟;
- 队列重分配;
- 消费重平衡;
- 重试增加。
应用应配置:
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
告警:
- 无 Controller leader;
- 仲裁节点不可用;
- 副本长期未同步;
- 频繁切换;
- epoch 异常变化;
- 副本数量低于预期。
18.9 演练清单
- 重启主 Broker;
- 重启副本;
- 关闭一个 Controller;
- 关闭多数 Controller;
- 模拟网络分区;
- 磁盘满;
- NameServer 不可用;
- 客户端重连;
- 旧主恢复;
- 跨可用区断连。
演练要验证数据位点、消息完整性、路由状态和业务对账结果,而不只是看服务是否恢复。
本章小结
Controller 模式把自动选主、角色裁决和 fencing 引入 RocketMQ 高可用体系,降低人工恢复成本和脑裂风险。高可用能力依赖仲裁拓扑、副本同步、NameServer 路由和客户端重试策略共同工作。生产上必须监控 epoch、副本差距和切换次数,并通过真实故障演练验证。
思考题
- 自动选主为什么要选择位点最新的副本?
- epoch 如何防止旧主继续写入?
- Controller 集群为什么需要奇数投票节点?
- NameServer 故障时客户端为什么可能仍能发送?
- 为什么副本长期不同步比一次切主更危险?