交换机和队列联合
本指南涵盖了与集群联合相关的各种主题,包括交换机和队列的联合。
概述
联合插件的主要目标是在不需集群的情况下,在代理之间传输消息。这有很多好处。
节点或集群的松散耦合
联合插件可以在不同管理域中的代理(或集群)之间传输消息
- 它们可能托管在不同的数据中心,甚至可能位于不同的洲
- 它们可能具有不同的用户、虚拟主机、权限和用途
- 它们可能运行在不同版本的 RabbitMQ 和 Erlang 上
- 它们可能具有不同的规模
- 它们可能是
广域网友好性
联合插件通信完全异步,并假设集群之间的连接会不时出现故障。因此,它可以很好地容忍间歇性连接,并且不会在远程集群之间创建耦合(在可用性方面)。
特定性
代理可以包含联合的和仅本地的组件,以最佳地适应系统的所需架构。
随着连接节点数量的增加,可扩展性
联合不需要在N个代理之间进行O(n2)连接(尽管这是设置的最简单方法)。
它做了什么?
联合插件使联合交换机和队列成为可能。联合交换机或队列可以接收来自一个或多个远程集群(称为上游)的消息(更准确地说:存在于远程集群中的交换机和队列)。
联合交换机可以将上游发布的消息路由到本地队列。当远程队列本身没有任何消费者在线时,联合队列允许本地消费者接收来自上游队列的消息。
联合链接连接到上游的方式与应用程序连接的方式基本相同。因此,它们可以连接到特定的 vhost,使用 TLS,使用多个身份验证机制。
联合文档被组织成许多更集中的指南
联合是如何设置的?
设置联合涉及两个步骤
- 首先,必须定义一个或多个上游。它们为联合提供有关如何连接到其他节点的信息。这可以通过运行时参数或联合管理插件来完成,该插件会向管理 UI添加一个联合管理选项卡。
- 要启用联合,必须声明一个或多个策略以匹配交换机或队列。该策略将使它们成为联合的。
入门
联合插件包含在 RabbitMQ 发行版中。要启用它,请使用rabbitmq-plugins
rabbitmq-plugins enable rabbitmq_federation
如果使用管理 UI,建议也启用rabbitmq_federation_management
rabbitmq-plugins enable rabbitmq_federation_management
在集群中使用联合时,集群的所有节点都应启用联合插件。
有关联合上游的信息存储在 RabbitMQ 数据库中,与用户、权限、队列等一起存储。联合涉及三个级别的配置
在实践中,对于简单的用例,您几乎可以忽略上游集的存在,因为有一个隐式定义的名为all
的上游集,所有上游都将添加到其中。
上游和上游集都是运行时参数的实例。与交换机和队列一样,每个虚拟主机都有自己独立的参数和策略集。有关参数和策略的更通用信息,请参阅有关参数和策略的指南。有关联合使用的参数的完整详细信息,请参阅联合参考。
参数和策略可以通过三种方式设置
- 使用CLI 工具
- 如果启用了扩展插件(
rabbitmq_federation_management
),则在管理 UI 中 - 使用 HTTP API
HTTP API 存在一个限制:它不支持管理上游集。
一个基本示例
在这里,我们将联合所有内置交换机(默认交换机除外),并使用单个上游。上游将在断开连接时缓冲消息长达一个小时(3600000 毫秒)。
要定义上游,请使用以下示例之一,每个选项卡一个
- bash
- PowerShell
- 管理 UI
- HTTP API
rabbitmqctl set_parameter federation-upstream my-upstream \
'{"uri":"amqp://target.hostname","expires":3600000}'
rabbitmqctl.bat set_parameter federation-upstream my-upstream `
'"{""uri"":""amqp://target.hostname"",""expires"":3600000}"'
导航到“管理”>“联合上游”>“添加新的上游”。在“名称”旁边输入“my-upstream”,在“URI”旁边输入“amqp://target.hostname”,在“过期时间”旁边输入 36000000。点击“添加上游”。
PUT /api/parameters/federation-upstream/%2f/my-upstream
{"value":{"uri":"amqp://target.hostname","expires":3600000}}
然后定义一个策略,该策略将匹配内置交换机并使用此上游
- bash
- PowerShell
- 管理 UI
- HTTP API
rabbitmqctl set_policy --apply-to exchanges federate-me "^amq\." \
'{"federation-upstream-set":"all"}'
rabbitmqctl.bat set_policy --apply-to exchanges federate-me "^amq\." `
'"{""federation-upstream-set"":""all""}"'
导航到“管理”>“策略”>“添加/更新策略”。在“名称”旁边输入“federate-me”,在“模式”旁边输入“^amq.”,从“应用于”下拉列表中选择“交换机”,并在第一行“策略”旁边输入“federation-upstream-set” = “all”。点击“添加”策略。
PUT /api/policies/%2f/federate-me
{"pattern":"^amq\.", "definition":{"federation-upstream-set":"all"}, "apply-to":"exchanges"}
定义的策略将使_名称以“amq.”开头的交换机(所有内置交换机,默认交换机除外)具有(隐式)低优先级,并使用隐式创建的上游集“all”进行联合,其中包括我们新创建的上游。
任何其他优先级大于 0 的匹配策略都将优先于此策略。请记住,federate-me
只是我们在此示例中使用的名称,您可以在其中使用任何您想要的字符串。
内置交换机现在应该已联合,因为它们与策略匹配。您可以通过检查管理中的交换机列表或使用以下命令来检查策略是否已应用于交换机
rabbitmqctl list_exchanges name policy | grep federate-me
并且您可以检查每个交换机的联合链接是否已启动,方法是使用“管理”>“联合状态”>“正在运行的链接”或使用以下命令
# This command will be available only if federation plugin is enabled
rabbitmqctl federation_status
通常,对于应用于交换机的每个上游,都会有一个联合链接。例如,如果三个交换机每个都有两个上游,则将有六个链接。
对于简单的使用,这应该是您需要的全部 - 您可能需要查看AMQP URI 参考。
联合参考包含有关上游参数和上游集的更多详细信息。
联合连接(链接)故障
联合使用的节点间连接基于 AMQP 0-9-1 连接。联合链接可以被操作员视为特殊类型的客户端。
如果链接发生故障,例如由于网络中断,它将尝试重新连接。重新连接周期是在上游定义中定义的可配置值。有关设置上游和上游集的更多详细信息,请参阅联合参考。
链接通常会无限期地尝试恢复,但有些情况下它们会放弃
- 故障率过高(最大容忍率取决于上游的
reconnect-delay
,但默认情况下通常是每隔几秒钟发生一次故障)。 - 链接无法再找到其“源”队列或交换机。
- 策略以某种方式更改,以至于链接认为自己不再需要。
通过增加上游的reconnect-delay
,可以容忍更高的链接故障率。这主要与具有中等或大量活动链接的 RabbitMQ 安装相关。
联合集群
集群可以像单个代理一样使用联合链接在一起。总结一下集群和联合是如何交互的
- 您可以在下游集群中的任何节点上定义策略和参数;在一个节点上定义后,它们将应用于所有节点。
- 交换机联合链接将在下游集群中的任何节点上启动。如果它们所在的节点崩溃或停止,它们将故障转移到其他节点。
- 队列联合链接将在与下游队列相同的节点上启动。如果下游队列是复制队列,它们将在与领导者相同的节点上启动,并在任何未来的领导者选举后在与新领导者相同的节点上重新创建。
- 要连接到上游集群,您可以在单个上游中指定多个 URI。联合链接过程将在每次尝试连接时随机选择其中一个 URI。
使用 TLS 保护联合连接
从 Erlang 26 开始,TLS 实现默认启用TLS 客户端对等方验证。
如果未配置客户端 TLS 证书和密钥对,则启用 TLS 的联合链接将无法连接。如果不需要对等方验证,可以将其禁用,否则必须为启用 TLS 的联合链接配置证书和私钥对。
联合连接(链接)可以使用 TLS 保护。由于联合在底层使用 RabbitMQ 客户端,因此需要同时配置源代理以侦听 TLS 连接,并配置联合/Erlang 客户端以使用 TLS。
要配置联合以使用 TLS,需要
- 使用
amqps
URI 方案而不是amqp
- 指定 CA 证书和客户端证书/密钥对,以及其他参数(即启用或禁用对等方验证、对等方验证深度)通过URI 查询参数
- 配置 Erlang 客户端以使用 TLS
就像使用“常规”客户端连接一样,服务器的 CA 应该在运行联合链接的节点上受信任,反之亦然。
联合链接监控
联合交换或队列与上游的每个组合都需要一个链接才能运行。这是从上游检索消息并将其重新发布到下游的过程。您可以使用 rabbitmqctl
和管理插件监控联合链接的状态。
使用 CLI 工具
可以使用RabbitMQ CLI 工具检查联合链接状态。
调用
# This command will be available only if federation plugin is enabled
rabbitmqctl federation_status
这将输出目标节点上运行的联合链接列表(而非集群范围)。它包含以下键
参数名称 | 描述 |
类型 | 根据此链接相关的联合资源类型,为 |
名称 | 联合交换或队列的名称 |
虚拟主机 | 包含联合交换或队列的虚拟主机 |
上游名称 | 此链接连接到的上游的名称 |
状态 | 链接的状态
|
连接 | 此链接的连接名称(来自配置) |
时间戳 | 上次状态更新的时间戳 |
这是一个示例
# This command will be available only if federation plugin is enabled
rabbitmqctl federation_status
# => [[{type,<<"exchange">>},
# => {name,<<"my-exchange">>},
# => {vhost,<<"/">>},
# => {connection,<<"upstream-server">>},
# => {upstream_name,<<"my-upstream-x">>},
# => {status,{running,<<"<rabbit@my-server.1.281.0>">>}},
# => {timestamp,{{2020,3,1},{12,3,28}}}]]
# => ...done.
使用管理 UI
启用rabbitmq_federation_management
插件,该插件使用一个新页面扩展管理 UI,以显示集群中的联合链接。它可以在“管理”>“联合状态”下找到,或者使用 GET /api/federation-links
HTTP API 端点。
故障排除
联合链接未启动
联合链接在以下情况下启动
- 有一个已配置的上游(或一组上游)
- 有一个与某些交换或队列匹配的策略
- 联合可以连接到目标上游
因此,为了缩小问题的范围,建议的步骤是
检查联合上游
- bash
- PowerShell
- 管理 UI
- HTTP API
rabbitmq-diagnostics list_parameters --formatter=pretty_table
rabbitmq-diagnostics.bat list_parameters --formatter=pretty_table
确保已启用rabbitmq_federation_management
插件。
导航到“管理”>“联合上游”。
GET /api/parameters
检查策略
在 RabbitMQ 中,一次只能应用一个策略,并且在 N 个具有相同优先级的策略中,将随机选择一个。
换句话说,当存在与旨在联合的交换或队列匹配的冲突策略时,启用联合的策略不保证是有效的策略。
使用显式不同的策略并避免 --apply-to all
的策略将降低遇到此问题的风险。