联邦交换器
概述
本指南涵盖联邦交换器(Federated Exchanges),这是 Federation 插件所提供的功能的一个子集。
涵盖的主题包括:
另有一份独立的 Federation 插件参考指南可供查阅。
交换器联邦是一种机制,它允许将一个位置(称为“上游”或源)的交换器中的消息流复制到其他位置(“下游”)的交换器中。下游是独立的节点或集群,可以跨越广域网(地理区域)。复制过程是异步的,并且可以容忍连接故障。
联邦交换器会链接到其他交换器。从概念上讲,发布到上游交换器的消息会被复制到联邦交换器,就好像它们被直接发布到联邦交换器一样。上游交换器无需重新配置。它们被假定位于单独的节点或单独的集群中。
上游定义是一个带有特定识别查询参数的 URI,用于控制链接连接参数。上游可以使用 CLI 工具 或带有 额外插件 的 HTTP API 进行管理。
下图显示了一个节点中的单个上游交换器(源交换器)链接到另一个节点中的单个下游交换器(联邦交换器):
使用交换器联邦时,通常只有集群中一部分交换器被联邦化。某些交换器可能本质上是属于该“站点”(集群)及其用途的本地交换器。
交换器联邦会在可能时将绑定从下游传播到上游。如果需要,它还会应用优化并选择性地传播消息。这将在后续章节中介绍。
用例
联邦交换器可用于将特定类型的消息流复制到远程位置。结合持续的模式同步以及队列和消息 TTL,这可用于在受控的时间窗口内维护具有相当新数据量的热备环境。
另一种用法是实现大规模扇出(fanout),即一个集群中的单个“源”交换器(充当源,无需联邦化)可以被其他代理中的许多其他联邦交换器声明为上游。反过来,每一个交换器都可以成为更多交换器的上游,以此类推。
请参阅下方的拓扑示例图了解一些可能的安排。
限制
交换器联邦支持所有内置的交换器类型。第三方交换器类型可能会根据其语义而正常工作。
默认交换器(名称为空白)无法被联邦化,因为它不是典型的交换器,并且依赖于其他交换器类型不使用的节点本地优化。
内部属性设置为 true 的交换器由 RabbitMQ 声明并内部使用,无法被联邦化。
使用与配置
联邦配置使用运行时参数和策略,这意味着它可以随着系统拓扑的变化而实时配置和重新配置。涉及两个关键配置部分:
- 上游(Upstreams):这是联邦系统中的远程端点。
- 联邦策略(Federation policies):这些策略控制哪些交换器被联邦化以及它们将连接到哪些上游(源)。
这两者都是在下游节点或集群上配置的。
要添加上游,请使用 rabbitmqctl set_parameter 命令。它接受三个参数:
- 参数类型,
federation-upstream - 联邦策略将引用的上游名称
- 包含至少一个强制键
uri的上游定义 JSON 文档
以下示例配置了一个名为 "origin" 的上游,可以通过 remote-host.local:5672 进行连接:
- 使用 rabbitmqctl (bash)
- 使用 rabbitmqadmin (bash)
- 使用 rabbitmqctl (PowerShell)
- 使用 PowerShell 的 rabbitmqadmin.exe
# Adds a federation upstream named "origin"
rabbitmqctl set_parameter federation-upstream origin '{"uri":"amqp://remote-host.local:5672"}'
# Adds a federation upstream named "origin"
rabbitmqadmin federation declare_upstream_for_exchanges --name origin \
--uri "amqp://remote-host.local:5672"
# Adds a federation upstream named "origin"
rabbitmqctl.bat set_parameter federation-upstream origin '"{""uri"":""amqp://remote-host.local:5672""}"'
# Adds a federation upstream named "origin"
rabbitmqadmin.exe federation declare_upstream_for_exchanges --name origin ^
--uri "amqp://remote-host.local:5672"
更多上游定义参数详见联邦参考指南。
指定上游后,可以添加控制联邦的策略。它像任何其他策略一样添加,使用:
- 使用 rabbitmqctl (bash)
- 使用 rabbitmqadmin (bash)
- 使用 rabbitmqctl (PowerShell)
- 使用 PowerShell 的 rabbitmqadmin.exe
# Adds a policy named "exchange-federation"
rabbitmqctl set_policy exchange-federation \
"^federated\." \
'{"federation-upstream-set":"all"}' \
--priority 10 \
--apply-to exchanges
# Adds a policy named "exchange-federation"
rabbitmqadmin policies declare \
--name "exchange-federation" \
--pattern "^federated\." \
--definition '{"federation-upstream-set":"all"}' \
--priority 10 \
--apply-to "exchanges"
# Adds a policy named "exchange-federation"
rabbitmqctl.bat set_policy exchange-federation `
"^federated\." `
'"{""federation-upstream-set"":""all""}"' `
--priority 10 `
--apply-to exchanges
# Adds a policy named "exchange-federation"
rabbitmqadmin.exe policies declare ^
--name "exchange-federation" ^
--pattern "^federated\." ^
--definition "{""federation-upstream-set"":""all""}" ^
--priority 10 ^
--apply-to "exchanges"
在上面的示例中,该策略将匹配默认虚拟主机中名称以 federated. 为前缀的交换器。这些交换器将为所有已声明的上游建立联邦链接。策略名称为 exchange-federation。与任何策略一样,如果多个策略匹配一个交换器,将使用优先级最高的策略。即使优先级相同,多个策略定义也不会合并。
配置完成后,将为每个匹配的交换器和上游对打开一个联邦链接(连接)。这里的“匹配交换器”是指被联邦策略模式匹配到的交换器。如果没有交换器匹配,则不会启动任何链接。
要停用匹配交换器的联邦功能,请使用其名称删除该策略:
rabbitmqctl clear_policy exchange-federation
复杂拓扑与循环处理
一个联邦交换器可以作为另一个联邦交换器的“上游”。甚至可以形成“循环”,例如,交换器 A 声明交换器 B 为其上游,而交换器 B 声明交换器 A 为其上游。允许更复杂的多重连接安排。
然而,这种复杂的拓扑结构将变得越来越难以理解和排查。
为了防止消息被持续复制和重新路由(在永无止境的循环中),对消息通过链接被复制的次数设置了限制(请参阅下文的 max-hops)。
建议所有通过联邦链接的交换器类型相同。混合类型可能会且很可能会导致令人困惑的路由行为。
实现细节
代理间通信是使用 AMQP 0-9-1(可选择使用 TLS 加密)实现的。绑定被组合在一起,当下游的绑定发生更改时,绑定操作(例如 queue.bind 和 queue.unbind 命令)会被发送到链接的上游侧。
因此,交换器仅接收其拥有绑定的消息。绑定与上游异步复制,因此添加或删除绑定的效果仅保证最终会显现。
消息被缓冲在上游交换器集群中创建的内部声明队列中。这被称为上游队列。正是上游队列通过组合绑定绑定到上游交换器。可以在上游配置中调整此队列的一些属性。
这是一张详细的图表,展示了单个联邦交换器链接到单个上游交换器的情况,包括由联邦插件创建的(以灰色显示)上游队列和绑定。上游链接上的粗箭头指示由联邦交换器重新发布的消息。图中显示了一些潜在的发布者客户端,它们同时向两个交换器发布消息。

发布到任一交换器的消息都可能被绑定到联邦交换器的队列接收,但直接发布到联邦交换器的消息不能被绑定到上游交换器的队列接收。
拓扑结构示例
我们演示了一些联邦拓扑示例。在这些图表中,由 指示的 RabbitMQ 代理可以是节点集群或独立节点。
| 拓扑 | 描述 |
| 联邦交换器对 | 在这种对称安排中,每个交换器都链接到另一个。图中展示了连接到每个代理的发布者和消费者。两个消费者都可以接收由任一发布者发布的消息。
两个链接声明时均使用了 |
| 完全图 | 这种安排是联邦交换器对的模拟,但针对的是三个交换器。每个交换器都链接到其他两个交换器。
同样使用 |
| 扇出(Fan-out) | 一个源交换器(无需联邦化)被一个交换器树链接,该树可以延伸到任何深度。在这种情况下,发布到源交换器的消息可以被连接到树中任何代理的任何消费者接收。
由于没有循环,设置 |
| 环形 | 在这个由六个代理组成的环中,每个联邦交换器仅链接到环中的另一个交换器。
这种拓扑结构虽然在队列和连接方面成本相对较低,但与完全连接的图相比相当脆弱。一个代理(或连接)故障就会破坏环。 |



