上一篇解释了镜像队列为什么必须被废弃——异步主从复制在分布式环境下有根本缺陷。这一篇讲它的继任者:Quorum Queue(仲裁队列)。这是 RabbitMQ 4.0 之后官方主推的高可用队列类型,也是当前核心业务队列的首选。
Quorum Queue 的核心是用 Raft 共识算法重做了消息复制。理解它的关键,不在于背 Raft 的术语(leader/follower/term/log),而在于理解它和镜像队列在「可靠性保证」上的本质区别——以及这个区别带来的能力与代价。
Quorum 的核心:多数派确认才算写入
镜像队列是「master 写入就成功,异步复制给 mirror」。Quorum Queue 反过来:leader 写入后,必须等多数节点(quorum)确认复制成功,才向生产者返回 ack。
举例:一个 3 节点的 Quorum Queue,多数派是 2。生产者发一条消息:
- 消息发到 leader 节点。
- leader 把消息追加到自己的 Raft 日志,并发给另外两个 follower。
- 只要至少一个 follower 确认(加上 leader 自己,凑够多数 2),leader 就认为这条消息「已提交」,向生产者返回 ack。
- 剩下那个还没确认的 follower,leader 会继续重试同步。
这个机制的关键意义:生产者收到 ack 时,消息已经安全地存在于多数节点上。此时即使 leader 崩溃,剩下的多数派里一定有这条消息,新的 leader 会继续提供服务,消息不会丢。这就是「强一致」——确认即持久,不存在镜像队列那种「确认了却丢失」的窗口。
Raft 怎么避免脑裂
Quorum Queue 用 Raft 的领导者选举机制,从根本上避免了镜像队列的脑裂问题。核心是 「多数派才能选出 leader」 这个规则:
- 网络分区把 3 节点集群分成「2 节点」和「1 节点」两半。
- 「2 节点」那半凑够多数(2 ≥ 2),能选出新 leader,继续提供服务。
- 「1 节点」那半凑不够多数(1 < 2),无法选出 leader,自我暂停(不可写)。
- 分区恢复,少数派重新加入多数派,同步日志。
这个机制保证任何时刻最多一个 leader 能接受写入,从根上杜绝了双 master 脑裂。少数派宁可不可用,也不冒险写不一致的数据——这是「CP」(一致性优先于可用性)的选择,和镜像队列的「AP」(可用性优先)截然不同。
推论:Quorum Queue 的可用性要求是「多数节点存活」。3 节点能容忍 1 个挂,5 节点能容忍 2 个挂。这是部署 Quorum 时节点数规划的依据——通常 3 或 5 个节点(奇数,避免浪费)。
Raft 日志:消息的真正载体
Quorum Queue 里,消息存在哪?答案是 Raft 日志。每个节点维护一个 append-only 的 Raft 日志,消息就是日志里的条目。
这和经典队列的「ETS + 消息存储」完全不同:
- 经典队列:消息在 ETS(内存)和消息存储(磁盘),复制靠镜像队列的 GM 协议。
- Quorum Queue:消息在 Raft 日志(磁盘),复制是 Raft 协议的一部分。
Raft 日志是 append-only(只追加),这种结构有两个好处:一是写入是顺序的(顺序 IO 快),二是日志本身就是消息的持久化记录,不需要单独的「消息存储」层。消费时,消费者按日志顺序读取,ack 后日志里对应条目可以被压缩清理。
这种「日志即存储」的设计,其实和 Kafka 的 partition log 是一个思路——消息本身就是一份有序日志。差别在 Kafka 的 log 是按 offset 消费且不删,Quorum 的 log 是消费即删(队列语义)。
Quorum Queue 的代价
强一致不是免费的,Quorum Queue 的代价:
写入延迟更高。 每条消息要等多数节点确认,比镜像队列的「本地写就返回」慢。延迟增量主要来自「等 follower 确认」的网络往返。在跨可用区部署时(节点物理距离远),这个延迟会更明显。
吞吐不如经典队列。 共识协议本身有开销,且写入要落 Raft 日志(磁盘)。Quorum Queue 的吞吐通常低于经典队列,不适合海量吞吐场景。
资源占用更高。 每个节点都维护完整的 Raft 日志副本,磁盘和内存占用比单机队列大。社区讨论中的经验数据是 Quorum 的 RAM 占用比经典镜像队列高 50%–60%(非官方基准,作为量级参考)。
特性受限。 Quorum Queue 不支持所有经典队列的特性。最典型的是消息优先级(早期不支持,后续版本逐步补齐但有条件)。另外 Quorum 会忽略消息的 delivery_mode,强制把消息持久化到磁盘——因为它本来就是为可靠设计,不存在「非持久化」的概念。设计时要核对特性矩阵。
这些代价都指向同一个判断:Quorum Queue 是为「不能丢消息」的核心业务队列设计的,它的强一致和容错是用性能和资源换来的。
什么时候该用 Quorum Queue
把 Quorum 的特性和代价放一起,适用场景就清晰了:
该用 Quorum Queue:
- 订单、支付、对账、金融交易——丢一条消息就是事故的核心业务队列。
- 需要高可用(节点故障自动 failover,不丢消息)。
- 能接受比经典队列略低的吞吐和略高的延迟。
不该用 Quorum Queue:
- 海量吞吐的日志/数据管道——用 Stream 或 Kafka。
- 临时队列、RPC 回复队列——用经典队列(这些场景不需要强一致)。
- 对延迟极度敏感的在线任务——经典队列(单机)延迟更低。
一个常见的部署形态是混合使用:核心业务队列用 Quorum(保可靠),临时/辅助队列用经典(保性能),数据管道用 Stream(保吞吐)。不是所有队列都要用 Quorum,按业务对可靠性的要求分级选型。
部署 Quorum 的几个要点
节点数用奇数。 3 或 5 个节点。偶数节点(如 4)的容错能力和奇数(3)一样(都容忍挂 1 个),却多花一台机器。5 节点容忍挂 2 个,是更高可用要求的配置。
跨可用区部署。 Quorum 的多数派要分散在不同可用区,这样单个 AZ 故障不影响多数派。比如 3 节点分散在 3 个 AZ,任意 1 个 AZ 挂了,剩余 2 个仍是多数。
控制集群规模。 Quorum 的 Raft 协议在大集群下开销显著,官方建议节点数不超过 7。更大的集群反而降低性能。
消息会被强制持久化。 Quorum Queue 会忽略消息的 delivery_mode,无论发布时标的是 transient 还是 persistent,都一律写入磁盘(这是 Quorum 保证可靠性的前提,不是报错)。所以发到 Quorum 的消息天然持久化,不需要也不能走「非持久化」路径。
收束:Quorum 是 RabbitMQ 的可靠性未来
Quorum Queue 是 RabbitMQ 在存储可靠性上的「正确答案」。它用 Raft 共识彻底解决了镜像队列的脑裂和丢失问题,代价是性能和资源。核心业务队列选它,是对「不能丢消息」这个硬约束的正面对答。
下一篇讲 RabbitMQ 的第三种队列类型——Stream,它代表了另一种思路:不追求队列语义,而是做类 Kafka 的日志流。
关于十三Tech
我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。我相信 AI 是程序员的最佳搭档。想跟完这套「图解 RabbitMQ」,欢迎关注公众号 「十三Tech」。

