高可用架构
RabbitMQ 高可用需要分别处理节点接入、元数据、Queue 数据和跨地域链路。仅部署多个 RabbitMQ 节点并不代表消息已经复制。
高可用模块
| 模块 | 高可用职责 | 关键边界 |
|---|---|---|
| 客户端多地址/负载均衡 | 节点故障后重新建立连接 | 连接恢复不等于未确认发布一定失败或成功 |
| RabbitMQ Cluster | 共享拓扑和安全元数据 | 不自动复制 Classic Queue 消息 |
| Quorum Queue | 通过 Raft 复制 Queue 数据并选举 Leader | 必须保持多数副本在线 |
| Stream | 复制追加日志并支持消费重放 | 消费和保留语义不同于普通 Queue |
| Federation/Shovel | 跨集群异步传递消息 | 不是同步共识,存在延迟和重复 |
Quorum Queue
Quorum Queue 是业务消息高可用的主线。每个 Queue 形成独立 Raft 副本组,由一个 Leader 接收操作,多数副本确认后提交。
三副本可以容忍一个副本失效,五副本可以容忍两个,但会增加网络、磁盘和恢复成本。使用偶数副本不会提高可容忍故障数,通常选择三个或五个成员。
失去多数派时,Queue 停止处理需要共识的操作。这是为了避免网络分区两侧分别接受不一致写入。
节点故障流程
- 客户端与故障节点的 Connection 中断。
- 客户端选择其他节点重新连接并恢复 Channel、Consumer 和拓扑。
- 如果 Quorum Leader 失效,剩余多数副本选举新 Leader。
- 未被 Confirm 的发布结果是不确定的,Producer 应幂等重试。
- 未 Ack 的 Delivery 会重新投递,Consumer 应保证业务幂等。
自动连接恢复不能代替业务重试。恢复过程中 Publisher Confirm 序列、临时 Queue、Exclusive Queue 和 Consumer Tag 都需要检查。
接入层
客户端可以配置多个 Endpoint,或使用 TCP 负载均衡器。负载均衡器必须按 AMQP 端口做健康检查,不能只检查节点管理页面。
连接应在节点之间合理分布,但 Quorum Queue 的写入仍由其 Leader 协调。跨节点代理会增加一次内部转发,因此还要观察 Leader 分布。
跨地域
不建议把高延迟 WAN 节点直接组成一个 RabbitMQ Cluster。跨地域通常使用独立集群加 Federation 或 Shovel,并接受异步复制边界。
跨地域设计必须明确:
- 是否允许重复和乱序;
- 主站点恢复后如何避免循环转发;
- DNS、流量入口和 Consumer 如何切换;
- RPO/RTO 与未复制消息如何补偿。
故障矩阵
| 故障 | 预期行为 | 数据风险 |
|---|---|---|
| 单 RabbitMQ 节点故障 | 客户端重连;Quorum Queue 重新选主 | 未 Confirm 发布结果不确定 |
| 少数 Quorum 副本故障 | 多数派继续服务 | 容错余量下降,应先恢复副本 |
| 失去多数派 | Queue 停止可用 | 不应强制形成两个独立 Leader |
| Consumer 故障 | 未 Ack 消息重新投递 | 业务可能重复执行 |
| 单数据中心故障 | 由跨集群灾备方案接管 | 取决于 Federation/Shovel 延迟 |
验证清单
- 关闭 Leader 节点,验证选主时间和 Publisher Confirm;
- 关闭一个副本,验证多数派写入和副本补齐;
- 模拟网络分区,验证少数派不会继续接受写入;
- 中断 Consumer,验证未 Ack 消息重投和业务幂等;
- 定期导出 Definitions,并演练从备份恢复用户、权限和拓扑。