1. 核心概念

RabbitMQ 的高可用主要体现在集群模式的选择上。原生的 RabbitMQ 集群分为两种模式:

  1. 普通集群模式(Standard Cluster):仅同步元数据(Metadata),不同步消息内容。
  2. 镜像队列模式(Mirror Queue):既同步元数据,也同步消息内容(这是实现 HA 的传统方式)。
  3. 仲裁队列(Quorum Queues):RabbitMQ 3.8+ 引入的新一代高可用模型,基于 Raft 协议。

2. 原理与架构

2.1 普通集群模式(非高可用)

  • 原理:多台机器组成集群,Queue 的元数据(定义)在所有节点同步,但 Queue 的实际消息数据只存储在创建它的那个节点(Master)上。
  • 缺点:如果 Master 节点宕机,该队列的消息将无法访问,直到节点恢复。如果磁盘损坏,消息丢失。此模式仅用于扩展吞吐量,不具备高可用性。

2.2 镜像队列模式(Classic HA)

  • 原理:将队列的消息数据在集群的其他节点上进行全量复制
    • Master:处理所有读写请求。
    • Slave:从 Master 同步数据。如果 Master 宕机,集群会自动将某个 Slave 提升为 Master。
  • 配置:通过 Policy 设置 ha-mode: all(所有节点镜像)或 ha-mode: exactly(指定副本数)。
  • 缺点
    • 性能损耗大:所有消息都要同步到所有 Slave,网络带宽压力大。
    • 同步阻塞:新节点加入时,全量同步历史数据会导致集群性能瞬间下降。

2.3 仲裁队列(Quorum Queues - 推荐)

  • 原理:基于 Raft 一致性协议 实现。
  • 特点
    • 数据安全性更高:只要半数以上节点写入成功即视为成功,避免了镜像队列的“脑裂”风险。
    • 性能更稳:相比镜像队列,在网络分区或节点故障时表现更稳定。
    • 限制:不支持非持久化消息(消息必须落盘)。

3. 性能与分区考量

  • 网络分区(Network Partition):RabbitMQ 对网络分区非常敏感。需配置 cluster_partition_handling 策略:
    • pause_minority:暂停少数派节点(推荐)。
    • autoheal:自动恢复,可能会丢数据。
  • 客户端连接:客户端应连接到 Load Balancer(如 HAProxy),由 LB 将请求分发到集群节点,实现客户端的高可用。

4. 示例与总结

回答总结: “RabbitMQ 的高可用不能靠‘普通集群模式’,因为它只同步元数据。 传统做法是开启镜像队列(Mirror Queue),配置策略让消息在多个节点间全量同步,Master 挂了 Slave 顶上。但镜像队列性能开销大,且在网络分区时容易出问题。 现在更推荐使用 RabbitMQ 3.8 引入的仲裁队列(Quorum Queues),它基于 Raft 协议,在保证数据一致性的同时,性能和稳定性都优于镜像队列。 此外,在架构上还需要配合 HAProxy + Keepalived 做前端的负载均衡和 VIP 漂移,保证客户端连接的高可用。”

# 开启镜像队列策略示例(命令行)
# 匹配所有以 'ha.' 开头的队列,在所有节点上进行镜像
rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}'