前面讲的集群、Quorum、网络分区,都假设节点在一个机房内(低延迟、高带宽)。但现实里很多业务要跨机房甚至跨地域——异地容灾、多地域部署、机房间数据同步。集群在这些场景下表现不佳(跨地域网络延迟会让 Raft 同步很慢),所以 RabbitMQ 提供了两个专门的机制:Federation 和 Shovel

这两个机制解决的是「跨 RabbitMQ broker 的消息流转」,但思路不同。理解它们的差别,才能选对跨机房方案。这一篇讲清楚。

为什么集群不适合跨机房

先说为什么不能直接用跨机房集群。前面讲过,集群节点间要频繁同步元数据,Quorum Queue 的写入要等多数节点 Raft 确认。如果节点跨机房(比如北京和上海,网络延迟 20–30ms),每次写入都要等跨地域的确认,吞吐会大幅下降;元数据同步的高延迟会让所有声明操作变慢;网络一旦抖动,跨地域的心跳超时会频繁触发分区判断。

所以跨机房不适合组单一集群。业界做法是「每个机房一个独立集群,集群之间用 Federation 或 Shovel 连接」。这样每个集群内部是低延迟的,跨机房只做必要的消息转发。

Federation:集群联邦

Federation(联邦) 是一种「连接两个独立 broker/集群」的机制,让消息可以在它们之间按路由规则流动。它的特点:

  • 松耦合:联邦的双方是独立的 broker/集群,各自有自己的用户、队列、元数据,互不干涉。联邦只是在它们之间建立消息转发。
  • 基于 AMQP:联邦用 AMQP 协议连接两个 broker,像普通的客户端连接一样,不需要特殊的网络通道。
  • 可按 Exchange 或 Queue 联邦
    • Exchange 联邦:上游 Exchange 的消息按路由规则复制到下游 Exchange。适合「多机房订阅同一份事件」。
    • Queue 联邦:把多个 broker 上的队列逻辑上连起来,消息在它们之间负载均衡。适合「跨机房分担消费」。
  • 单向或双向:可以单向联邦(A → B),也可以双向(A ↔ B)。

Federation 的典型场景:

  • 异地多活:北京集群和上海集群通过 Federation 互相同步关键事件,任一机房故障另一个能继续。
  • 多团队/多租户隔离:不同团队的 RabbitMQ 独立管理,但通过 Federation 共享某些事件。
  • 汇聚监控:各机房的告警/日志事件,通过 Federation 汇聚到一个中心集群统一处理。

Federation 的关键优势是松耦合和容错:联邦连接断了,两个集群各自继续独立运行,不会互相拖垮;连接恢复后自动续传。这比跨机房集群健壮得多。

Shovel:单向搬运

Shovel(铲子) 是另一种跨 broker 的机制,但更简单直接——它做的是**「从一个 broker 的队列里取消息,搬到另一个 broker 的队列」**,像一把铲子在两边来回搬运。

Shovel 的特点:

  • 单向:一条 Shovel 配置定义一个搬运方向(源 → 目标)。要双向就配两条。
  • 队列到队列:Shovel 从源队列消费,发布到目标 Exchange/队列。它是「消费+发布」的组合,中间可以做简单的转换。
  • 更底层、更可控:Shovel 不像 Federation 那样有「联邦 Exchange」的概念,它就是纯粹的搬运。配置更直接,但功能也更单一。

Shovel 的典型场景:

  • 数据迁移:从一个集群把存量消息搬到另一个集群(比如机房搬迁、版本迁移)。
  • 单向集成:把某个机房的特定队列内容同步到另一个机房的处理系统。
  • 跨协议/跨版本桥接:Shovel 可以连接不同版本、不同配置的 broker,做协议或格式转换。

Federation vs Shovel:怎么选

两者都做跨 broker 消息流转,但适用场景不同:

维度 Federation Shovel
模型 联邦(双向、多对多) 搬运(单向、点对点)
耦合度 较松,按路由规则流动 很松,纯搬运
配置粒度 Exchange/Queue 级别的联邦链接 队列到队列的搬运
典型场景 异地多活、多机房事件同步 数据迁移、单向集成
复杂度 较高(要理解联邦拓扑) 较低(搬就完了)

选择思路:

  • 需要持续的双向同步、多机房实时联动 → Federation。它就是为这种场景设计的。
  • 需要一次性的或单向的数据搬运 → Shovel。简单直接。
  • 不确定 → 先用 Shovel 试。Shovel 的配置简单、影响面小,试错成本低。Federation 的拓扑一旦建好,改动成本高。

跨机房容灾的设计原则

无论用 Federation 还是 Shovel,跨机房容灾有几个通用原则:

明确一致性预期。 跨机房同步通常是异步的(网络延迟不允许同步),所以跨机房的数据是「最终一致」。业务要容忍「主机房写入后,异地机房有延迟才看到」。强一致的需求不能靠跨机房 Federation 解决,要走别的路(比如业务层保证、或只在一个机房写)。

避免循环。 双向 Federation 或多条 Shovel 如果配错,可能形成消息循环(A 的消息发到 B,B 又发回 A,无限循环)。配置时要用 RoutingKey 或 queue 名做明确的单向控制。

监控联邦/搬运健康。 Federation 的 link 断了、Shovel 卡了,都会导致跨机房同步停滞。要监控这些组件的状态,断了及时告警。

网络是前提。 跨机房依赖公网或专线。专线的稳定性和带宽直接影响 Federation/Shovel 的效果。公网要做加密(TLS)和压缩,否则既不安全又费流量。

Federation 与 Shovel 的跨机房拓扑

收束:集群管单机房,Federation/Shovel 管跨机房

RabbitMQ 的多节点能力分两层:集群解决单机房的高可用和容量,Federation/Shovel 解决跨机房的连通和容灾。不要试图用跨机房集群解决一切——那会同时损害单机房性能和跨机房稳定性。正确的姿势是每机房一个集群,集群间按需用 Federation(持续同步)或 Shovel(定向搬运)连接。

阶段五「集群与高可用」到这里结束。最后一个阶段是运维与架构收束——监控排障闭环,以及整个系列的选型总结。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。我相信 AI 是程序员的最佳搭档。想跟完这套「图解 RabbitMQ」,欢迎关注公众号 「十三Tech」

十三Tech公众号二维码