交换机和队列 Federation
本指南涵盖了与集群 federation 相关的各种主题,包括交换机和队列
- Federation 概述
- Federation 有什么作用?
- 开始入门
- 一个基本示例
- Federation 连接
- Federating 集群
- Federation 对 TLS 的支持
- 监控 federation 链接状态
- 故障排除
概述
Federation 插件的高级目标是在已启用该插件但不属于同一集群的 Broker 之间复制或移动消息。这在很多方面都很有用。
节点或集群的松耦合
federation 插件可以在不同管理域中的 Broker(或集群)之间传输消息
- 它们可能托管在不同的数据中心,可能在不同的洲
- 它们可能具有不同的用户、虚拟主机、权限和目的
- 它们可能运行在不同版本的 RabbitMQ 和 Erlang 上
- 它们的大小可能不同
WAN 友好性
federation 插件通信完全是异步的,并假设集群之间的连接会不时失败。因此,它可以很好地容忍间歇性连接,并且不会在远程集群之间创建耦合(在可用性方面)。
特异性
Broker 可以包含 federated *和* 仅本地组件,以最好地适应系统所需的架构。
随着连接节点数量增长的可扩展性
Federation 不需要 *N* 个 Broker 之间 O(n2) 个连接(尽管这是设置事物最简单的方法)。
它有什么作用?
federation 插件使 *federate* 交换机和队列成为可能。一个 federated 交换机或队列可以从一个或多个远程集群接收消息,这些集群称为 *上游*(更准确地说:存在于远程集群中的交换机和队列)。
一个 federated 交换机将“重放”发布到其上游对应物的消息流,并将它们发布到本地队列或流。
当远程队列本身没有任何在线消费者时,federated 队列允许本地消费者从上游队列接收消息。
Federation 链接以上游应用程序大致相同的方式连接到上游。因此,它们可以连接到特定的 vhost,使用 TLS,使用多种 身份验证机制。
通常,federation 用于连接远程集群。但是,它也可以用于在同一集群内的 虚拟主机 之间移动数据。
Federation 文档组织成许多更集中的指南
- 交换机 federation:用于通过交换机将消息流复制到远程集群
- 队列 federation:用于在 N 个集群上创建一个“逻辑队列”,该队列将消息移动到消费者所在的位置(如果没有本地消费者)
- Federation 设置参考
Federation 如何设置?
设置 federation 涉及两个步骤
- 首先,必须定义一个或多个上游。它们为 federation 提供有关如何连接到其他节点的信息。这可以通过 运行时参数 或 federation 管理插件 完成,该插件向 管理 UI 添加了 federation 管理选项卡。
- 要启用 federation,必须声明一个或多个匹配交换机或队列的 策略。该策略将使匹配的对象(例如交换机)成为 federated,并且对于每个匹配项,将启动一个 federation 链接(与其他节点的连接)
开始入门
federation 插件包含在 RabbitMQ 发行版中。要启用它,请使用 rabbitmq-plugins
rabbitmq-plugins enable rabbitmq_federation
如果使用 管理 UI,建议也启用 rabbitmq_federation_management
rabbitmq-plugins enable rabbitmq_federation_management
在集群中使用 federation 时,集群的所有节点都应启用 federation 插件。
有关 federation 上游的信息存储在 RabbitMQ 数据库中,以及用户、权限、队列等。federation 涉及三个级别的配置
- 上游:每个 上游 定义一个远程连接端点。
- 上游集合:每个 上游集合组 将一组上游组合在一起以用于 federation。
- 策略:每个 策略 选择一组交换机、队列或两者,并将单个上游或上游集合应用于这些对象。
在实践中,对于简单的用例,您可以几乎忽略上游集合的存在,因为存在一个隐式定义的上游集合,称为 all
,所有上游都添加到其中。
上游和上游集合都使用 运行时参数 定义。与交换机和队列一样,每个虚拟主机都有自己独特的参数和策略集。有关参数和策略的更多通用信息,请参阅有关 参数和策略 的指南。有关 federation 使用的参数的完整详细信息,请参阅 federation 参考。
参数和策略可以通过三种方式设置
- 使用 CLI 工具
- 如果启用了扩展插件 (
rabbitmq_federation_management
),则在管理 UI 中 - 使用 HTTP API
HTTP API 有一个限制:它不支持上游集合的管理。
一个基本示例
在这里,我们将 federate 除默认交换机外的所有内置交换机,使用单个上游。上游将被定义为在断开连接时缓冲消息长达一小时 (3600000 毫秒)。
要定义上游,请使用以下示例之一,每个选项卡一个
- bash
- PowerShell
- 管理 UI
- HTTP API
# target.hostname is just an example, replace it with a URI
# of the target node (usually a member of a remote node/cluster,
# or a URI that connects to a different virtual host within the same cluster)
rabbitmqctl set_parameter federation-upstream my-upstream \
'{"uri":"amqp://target.hostname","expires":3600000}'
# target.hostname is just an example, replace it with a URI
# of the target node (usually a member of a remote node/cluster,
# or a URI that connects to a different virtual host within the same cluster)
rabbitmqctl.bat set_parameter federation-upstream my-upstream `
'"{""uri"":""amqp://target.hostname"",""expires"":3600000}"'
导航到 Admin
> Federation Upstreams
> Add a new upstream
。在名称旁边输入“my-upstream”,在 URI 旁边输入“amqp://target.hostname”,在 Expiry 旁边输入 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""}"'
导航到 Admin
> Policies
> Add / update a policy
。在“名称”旁边输入“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”对其进行 federation,其中包括我们新创建的上游。
任何其他优先级大于 0 的 匹配策略 都将优先于此策略。请记住,federate-me
只是我们用于此示例的名称,您可以在此处使用任何您想要的字符串。
内置交换机现在应该被 federated,因为它们与策略匹配。您可以通过检查管理中的交换机列表或使用以下命令来检查策略是否已应用于交换机
rabbitmqctl list_exchanges name policy | grep federate-me
您可以检查每个交换机的 federation 链接是否已启动,方法是使用 Admin
> Federation Status
> Running Links
或使用以下命令
# This command will be available only if federation plugin is enabled
rabbitmqctl federation_status
通常,每个应用于交换机的上游将有一个 federation 链接。因此,例如,对于三个交换机和每个交换机两个上游,将有六个链接。
对于简单的使用,这应该是您所需要的全部 - 您可能需要查看 AMQP URI 参考。
federation 参考 包含有关上游参数和上游集合的更多详细信息。
Federation 连接(链接)失败
Federation 使用的节点间连接基于 AMQP 0-9-1 连接。运营商可以将 Federation 链接视为一种特殊的客户端。
如果链接失败,例如由于网络中断,它将尝试重新连接。重新连接周期是一个可配置的值,在上游定义中定义。有关设置上游和上游集合的更多详细信息,请参阅 federation 参考。
链接通常会无限期地尝试恢复,但在某些情况下它们会放弃
- 失败率太高(最大容忍率取决于上游的
reconnect-delay
,但通常默认为每隔几秒失败一次)。 - 链接不再能找到其“源”队列或交换机。
- 策略发生更改,以至于链接认为自身不再必要。
通过增加上游的 reconnect-delay
,可以容忍更高的链接失败率。这主要与活动链接数量中等或较大的 RabbitMQ 安装有关。
Federating 集群
集群可以像单个 Broker 一样与 federation 链接在一起。总结集群和 federation 如何交互
- 您可以在下游集群中的任何节点上定义策略和参数;一旦在一个节点上定义,它们将应用于所有节点。
- 交换机 federation 链接将在下游集群中的任何节点上启动。如果它们运行的节点崩溃或停止,它们将故障转移到其他节点。
- 队列 federation 链接将在与下游队列相同的节点上启动。如果下游队列是 复制队列,它们将在与领导者相同的节点上启动,并且将在任何未来的领导者选举后在新领导者相同的节点上重新创建。
- 要连接到上游集群,您可以在单个上游中指定多个 URI。federation 链接进程将在每次尝试连接时随机选择这些 URI 之一。
使用 TLS 保护 Federation 连接
从 Erlang 26 开始,TLS 实现默认启用 TLS 客户端对等方验证。
如果未配置客户端 TLS 证书和密钥对,则启用 TLS 的 Federation 链接将无法连接。对于需要使用对等方验证的启用 TLS 的 Federation 链接,必须配置证书(公钥)和私钥对。
如果不需要对等方验证,则可以禁用它。
Federation 连接(链接)可以使用 TLS 进行保护。由于 Federation 在后台使用 RabbitMQ 客户端,因此既需要配置目标 Broker 以 监听 TLS 连接,也需要 Federation 使用 TLS。
要配置 Federation 使用 TLS,需要
- 在上游 URI 中,将方案的
amqp
替换为amqps
,并将端口5672
替换为5671
(假设使用默认端口,但显式指定端口) - 在同一个上游 URI 中,通过 URI 查询参数 指定 CA 证书和客户端证书/密钥对,以及其他参数(即 启用或禁用对等方验证,对等方验证深度)
- 可选地,通过 Erlang 客户端设置配置所有链接(以及可选的 Shovel)通用的 TLS 相关 设置或默认值
在以下示例中,上游 URI 被修改为使用 TLS 和客户端证书(公钥)和私钥对,但禁用了对等方验证(为了简单起见,建议在生产中使用)
- bash
- PowerShell
- 管理 UI
- HTTP API
# Note the TLS-related settings in the upstream URI field
rabbitmqctl set_parameter federation-upstream my-upstream \
'{"uri":"amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none","expires":3600000}'
#
rabbitmqctl.bat set_parameter federation-upstream my-upstream `
'"{""uri"":""amqps://target.hostname:5671?cacertfile=drive:\path\to\ca_bundle.pem&certfile=drive:\path\to\client_certificate.pem&keyfile=drive:\path\to\client_key.pem&verify=verify_none"",""expires"":3600000}"'
导航到 Admin
> Federation Upstreams
> Add a new upstream
。在名称旁边输入“my-upstream”,为 URI 粘贴 "amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none"
,然后在 Expiry 旁边输入 36000000。
单击添加上游。
PUT /api/parameters/federation-upstream/%2f/my-upstream
{"value":{"uri":"amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none","expires":3600000}}
这些示例使用带有四个附加 URI 查询参数 的 URI
cacertfile
:CA 证书捆绑文件,其中包含用于签署客户端证书和私钥对的一个或多个 CA 证书certfile
:客户端证书(公钥)keyfile
:客户端私钥verify
:控制对等方验证(在此特定示例中,禁用它)
就像“常规”客户端连接一样,如果启用 TLS 的 federation 链接需要执行对等方验证,则服务器的 CA 必须在运行 federation 链接的节点上受信任,反之亦然。
Federation 链接监控
federated 交换机或队列和上游的每个组合都需要运行一个链接。这是从上游检索消息并将其重新发布到下游的过程。您可以使用 rabbitmqctl
和管理插件来监控 federation 链接的状态。
使用 CLI 工具
可以使用 RabbitMQ CLI 工具 检查 Federation 链接状态。
调用
# This command will be available only if federation plugin is enabled
rabbitmqctl federation_status
这将输出目标节点上运行的 federation 链接列表(不是集群范围的)。它包含以下键
参数名称 | 描述 |
类型 |
|
名称 | federated 交换机或队列的名称 |
vhost | 包含 federated 交换机或队列的虚拟主机 |
upstream_name | 此链接连接到的上游的名称 |
状态 | 链接的状态
|
连接 | 此链接的连接名称(来自配置) |
时间戳 | 上次状态更新的时间戳 |
这是一个例子
# 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
插件,该插件使用显示集群中 federation 链接的新页面扩展了 管理 UI。可以在 Admin
> Federation Status
下找到它,或者使用 GET /api/federation-links
HTTP API 端点。
故障排除
Federation 链接未启动
当满足以下条件时,将启动 Federation 链接
- 存在已配置的上游(或一组上游)
- 存在与某些交换机或队列匹配的策略
- Federation 可以连接到目标上游
因此,为了缩小问题范围,建议的步骤是
检查 Federation 上游
- bash
- PowerShell
- 管理 UI
- HTTP API
rabbitmq-diagnostics list_parameters --formatter=pretty_table
rabbitmq-diagnostics.bat list_parameters --formatter=pretty_table
确保已启用 rabbitmq_federation_management
插件。
导航到 Admin
> Federation Upstreams
。
GET /api/parameters
检查策略
RabbitMQ 中一次只能应用一个策略,并且在 N 个具有相同优先级的策略中,将随机选择一个策略。
换句话说,当存在与旨在 federated 的交换机或队列匹配的冲突策略时,启用 federation 的策略不能保证是有效的策略。
使用显式不同的策略并避免 --apply-to all
的策略将降低遇到此问题的风险。