联合交换
概述
本指南介绍联合交换,它是 联合插件 提供的功能子集。
一些涵盖的主题包括
提供了一个单独的 联合插件参考 指南。
交换联合是一种机制,它允许通过一个位置(称为上游或源)中的交换传递的消息被复制到其他位置(下游)中的交换。下游是独立的节点或集群,可以跨越广域网(地理区域)。复制过程是异步的,并能容忍连接故障。
联合交换链接到其他交换。从概念上讲,发布到上游交换的消息将被复制到联合交换,就好像它们是直接发布到联合交换一样。上游交换不需要重新配置。假定它们位于单独的节点或单独的集群中。
上游定义是一个 URI,它包含某些识别查询参数,这些参数控制链接连接参数。可以使用 CLI 工具 或 HTTP API 与 附加插件 管理上游。
以下是一个图表,显示了一个节点中的单个上游交换(源交换)链接到另一个节点中的单个下游交换(联合交换)。
当使用交换联合时,通常仅联合集群中交换的一个子集。某些交换可能天生就是“站点”(集群)及其用途的本地交换。
交换联合将尽可能从下游传播到上游的 绑定。它还将在需要时应用优化并选择性地传播消息。这将在 后面的部分 中介绍。
用例
联合交换可用于将某些消息类型的流复制到远程位置。结合连续的 模式同步 和 队列和消息 TTL,这可用于在受控时间窗口内维护具有相当最新数据的热备。
另一个用途是实现大规模扇出,一个集群中单个“源”交换(充当源,无需联合)可以被其他集群中许多其他联合交换声明为上游。反过来,这些交换中的每一个又可以成为许多更多交换的上游,等等。
请参阅 下面的拓扑示例,以了解一些可能的排列方式。
局限性
交换联合支持所有内置交换类型。第三方交换类型可能取决于它们的语义而起作用。
默认交换(带有空白名称)不能联合,因为它不是典型的交换,并且依赖于其他交换类型不使用的节点本地优化。
将 internal 属性设置为 true
的交换由 RabbitMQ 声明和内部使用,不能联合。
使用和配置
联合配置使用 运行时参数和策略,这意味着它可以根据系统拓扑的变化动态配置和重新配置。涉及的配置有两个关键部分
- 上游:这些是联合系统中的远程端点
- 联合策略:这些控制哪些交换是联合的以及它们将连接到哪些上游(源)
这两者都在下游节点或集群上配置。
要添加上游,请使用 rabbitmqctl set_parameter
命令。它接受三个参数
- 参数类型,
federation-upstream
- 联合策略将引用的上游名称
- 一个上游定义 JSON 文档,至少包含一个必需键
uri
以下示例配置了一个名为“origin”的上游,它可以通过 remote-host.local:5672
联系。
- bash
- PowerShell
# Adds a federation upstream named "origin"
rabbitmqctl set_parameter federation-upstream 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""}"'
更多上游定义参数在 联合参考指南 中介绍。
指定上游后,可以添加一个控制联合的策略。它与任何其他 策略 一样添加,使用
- bash
- PowerShell
# 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"
rabbitmqctl.bat set_policy exchange-federation `
"^federated\." `
'"{""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 代理由 表示,它可以是节点集群或独立节点。
拓扑 | 描述 |
一对联合交换 | 在这种对称排列中,每个交换都链接到另一个。说明了连接到每个代理的发布者和消费者。两个消费者都可以接收任一发布者发布的消息。 两个链接都使用 |
完全图 | 这种排列类似于一对联合交换,但针对三个交换。每个交换都链接到其他两个交换。 同样使用 |
扇出 | 一个源交换(无需联合)由一个交换树链接,该树可以扩展到任何深度。在这种情况下,发布到源交换的消息可以被连接到树中任何代理的任何消费者接收。 由于没有循环,因此无需正确设置 |
环形 | 在这个由六个代理组成的环形中,每个联合交换仅链接到环形中的另一个交换。 与完全连接图相比,这种拓扑虽然在队列和连接方面相对便宜,但比较脆弱。一个代理(或连接)故障会破坏环形。 |