Skip to content

07 - 集群与高可用架构

面试高频度:⭐⭐⭐⭐ 考查方式:架构设计题、故障恢复题


一、为什么需要集群?

1.1 单节点 RabbitMQ 的问题

单节点 RabbitMQ 有三个致命缺陷:

问题后果
单点故障Broker 宕机 → 所有消息收发停止,业务系统瘫痪
容量上限单节点的内存和 CPU 有极限,消息量增长到一定程度就撑不住了
维护停机升级版本、修改配置都需要停机,影响业务可用性

集群的核心价值:通过多节点协作,消除单点故障,提升整体可用性和容量

1.2 集群的本质:共享元数据 + 数据复制

RabbitMQ 集群中所有节点共享元数据(Exchange、Queue、Binding 的定义),但消息数据的复制策略取决于队列类型——这是三种集群模式的本质区别。


二、三种集群模式

2.1 普通集群(Non-HA)——只共享元数据

原理:集群中所有节点都能看到同一个 Exchange 和 Queue 的定义(元数据同步),但消息只存在于 Queue 所在的那个节点上

Node 1 (Queue A 主节点)     Node 2      Node 3
┌──────────┐              ┌──────────┐  ┌──────────┐
│Queue A ✓ │              │Queue A   │  │Queue A   │
│(有消息)   │              │(只有元数据)│  │(只有元数据)│
└──────────┘              └──────────┘  └──────────┘

消息路由过程:如果 Consumer 连接到 Node 2 但 Queue A 在 Node 1 上,Node 2 会通过集群内部通信从 Node 1 拉取消息再转发给 Consumer。这个转发过程增加了网络延迟。

致命缺陷:Node 1 宕机后,Queue A 的消息全部不可用——没有自动故障转移机制。所以普通集群不能用于生产环境

2.2 镜像队列(Mirrored Queue)——全量复制(已废弃)

原理:在普通集群的基础上,通过 HA Policy 配置,让 Queue 的消息同步复制到其他节点。一个 Master 节点处理所有读写,多个 Slave 节点作为副本。

Node 1 (Master)         Node 2 (Slave)      Node 3 (Slave)
┌──────────┐           ┌──────────┐         ┌──────────┐
│Queue A ✓ │  ──同步──▶ │Queue A ✓ │ ──同步──▶│Queue A ✓ │
│(写入+ACK) │           │(副本)     │         │(副本)     │
└──────────┘           └──────────┘         └──────────┘

Master 宕机 → 最老的 Slave 自动提升为新 Master

镜像队列的同步机制:消息到达 Master 后,Master 会将消息同步发送给所有 Slave,Slave 确认收到后,Master 才向 Producer 返回 ACK。消费时,Master 处理 ACK 并通知 Slave 删除对应消息。

镜像队列为什么被废弃? 三个根本缺陷:

缺陷原因后果
性能差同步复制到所有节点,Slave 越多越慢写入吞吐量随节点数反比下降
数据不一致ACK 状态的同步是异步的Master 宕机时,部分已消费但 ACK 未同步的消息会被新 Master 重新投递
故障转移不可靠"最老的 Slave 提升为 Master"的选举策略太简单可能选出数据不完整的节点做 Master

2.3 仲裁队列(Quorum Queue)——Raft 共识(3.8+ 推荐)

原理:基于 Raft 共识协议实现的分布式队列。每个仲裁队列有一个 Leader 和多个 Follower,消息写入时需要多数派确认才算成功。

Node 1 (Leader)         Node 2 (Follower)    Node 3 (Follower)
┌──────────┐           ┌──────────┐         ┌──────────┐
│Queue A ✓ │  ──Raft──▶ │Queue A ✓ │ ──Raft──▶│Queue A ✓ │
│(Leader)  │           │(Follower) │         │(Follower) │
└──────────┘           └──────────┘         └──────────┘

写入规则:3 个节点中至少 2 个确认 → 写入成功
Leader 宕机 → 自动选举新 Leader(秒级)

为什么 Raft 比镜像队列更可靠?

维度镜像队列仲裁队列(Raft)
一致性模型异步复制,最终一致多数派写入,强一致
数据丢失风险Master 宕机可能丢已消费未同步 ACK 的数据只要多数节点存活,数据不丢
故障转移"最老 Slave"策略,简单但不可靠Raft Leader 选举,有完整的日志一致性保证
运维复杂度HA Policy 配置复杂,参数多x-queue-type=quorum 一个参数搞定

仲裁队列的多数派写入:以 3 节点为例,一条消息写入时 Leader 把它发给 2 个 Follower,只要 3 个节点中任意 2 个确认写入成功,就返回 ACK 给 Producer。这意味着即使 1 个节点宕机,剩余 2 个节点仍然能正常工作

仲裁队列的限制:不支持某些特性(如 priority queue、临时队列、某些 TTL 配置),但这些限制在生产场景中通常不重要。


三、集群的关键运维问题

3.1 网络分区(脑裂)

什么是网络分区? 集群中的节点因为网络故障被分成两个或多个互相不可达的分区。每个分区各自认为对方宕机了,可能各自选出新的 Leader,导致两个分区同时接受写入——数据出现不一致。

正常集群:     Node 1 ←→ Node 2 ←→ Node 3

网络分区后:   Node 1 + Node 2(分区 A)  |  Node 3(分区 B)
              多数派,正常工作             |  少数派,应该暂停

三种处理策略

策略行为适用场景
ignore不处理,等网络恢复后人工介入不推荐——数据可能不一致
pause_minority少数派分区自动暂停服务3 节点推荐——少数派知道自己是少数,主动暂停
autoheal网络恢复后自动重启少数派节点5+ 节点推荐

为什么 pause_minority 对 3 节点最合适? 3 节点集群最多容忍 1 个节点故障。当网络分区把集群分成 2+1 时,1 个节点的分区知道自己是少数派,主动暂停服务。2 个节点的分区继续正常工作。这样保证了整个集群只有一个"权威版本",不会出现脑裂。

3.2 负载均衡

集群前面通常加一层负载均衡器(HAProxy / Nginx),客户端通过负载均衡器连接到集群:

Client ──▶ HAProxy ──┬──▶ Node 1 (Leader)
                      ├──▶ Node 2 (Follower)
                      └──▶ Node 3 (Follower)

仲裁队列的优势:仲裁队列会自动将 Consumer 的连接路由到 Leader 节点,即使 Consumer 连接的是 Follower,消息也会从 Leader 获取。所以负载均衡器的策略不需要特别关心 Queue 的 Leader 位置。

3.3 节点类型

类型说明适用场景
disc元数据存储到磁盘,Broker 重启后元数据不丢生产必须——至少 2 个 disc 节点
ram元数据只存内存,读写更快,但重启后元数据丢失大规模集群中配合 disc 使用,提升元数据访问速度

四、集群最少需要几个节点?

队列类型最少节点推荐节点容忍故障数
普通队列230(无 HA)
镜像队列231(3 副本时)
仲裁队列33 或 51(3 节点)/ 2(5 节点)

为什么仲裁队列最少要 3 个节点? Raft 协议要求多数派确认。2 个节点时多数派 = 2,即任何一个节点宕机就无法写入——和单点故障没有区别。3 个节点时多数派 = 2,容忍 1 个故障。


五、面试常见追问

Q1:仲裁队列和镜像队列怎么选?

3.8+ 一律选仲裁队列。镜像队列已被官方标记为 deprecated(废弃)。仲裁队列基于 Raft,强一致性、故障转移更快、运维更简单。如果你的项目还在用镜像队列,面试时可以说"计划迁移到 Quorum Queue"。

Q2:集群中的 Queue 存在于几个节点?

  • 普通队列:只存在于 1 个节点
  • 镜像队列:存在于所有节点(ha-mode=all)或指定数量节点
  • 仲裁队列:存在于所有节点(默认),通过 x-quorum-initial-group-size 可以指定副本数

Q3:如何实现零停机迁移?

1. 新集群搭建完成
2. Federation 插件:旧集群 → 新集群同步消息
3. 逐步切换 Producer 到新集群
4. Consumer 消费完旧集群消息后切换
5. 关闭 Federation,下线旧集群

Federation 插件可以在两个集群之间建立消息同步通道,实现不停机迁移。


六、关联笔记

  • **RabbitMQ基础与核心概念** - 集群基础概念
  • **消息可靠性保障** - 与集群配合的可靠性方案
  • **SpringBoot整合RabbitMQ** - 集群配置示例

Knowledge4J — Java 知识库