跳到主要内容
版本: 4.1

联邦队列

概述

本指南涵盖联邦队列,这是联邦插件提供的功能子集。

涵盖的一些主题包括

单独的联邦插件参考指南可用。

除了联邦交换机之外,RabbitMQ 还支持联邦队列。此功能提供了一种跨节点或集群平衡单个逻辑队列负载的方法。它通过在本地队列没有消费者时将消息移动到其他联邦对等方(节点或集群)来实现。

虽然联邦交换机将其消息流从上游复制到一个或多个下游,但联邦队列将数据移动到消费者所在的位置,始终优先考虑本地消费者而不是远程消费者。联邦队列被认为是平等的对等方,它们之间没有像联邦交换机那样的“领导者/跟随者”关系。

联邦队列链接到其其他联邦对等方(称为上游队列)。它将从上游队列检索消息,以满足本地消费者对消息的需求。上游队列无需重新配置。它们被假定位于单独的节点或单独的集群中。

上游定义是一个 URI,其中包含某些已识别的查询参数,这些参数控制链接连接参数。可以使用CLI 工具或带有附加插件的 HTTP API 来管理上游。

下图演示了两个 RabbitMQ 节点中使用队列联邦连接的多个联邦队列和非联邦队列

Overview of federated queues

当使用队列联邦时,通常只有集群中的队列子集是联邦的。某些队列可能本质上是“站点”(集群)及其用途本地的。

使用场景

典型的用法是将相同的“逻辑”队列分布在多个 Broker 上。每个 Broker 将声明一个联邦队列,并将所有其他联邦队列作为上游。链接将在联邦对等方(节点或集群)上形成完整的双向图。

这种逻辑分布式队列能够比单个队列具有更高的容量。当存在一定程度的局部性时,它的性能最佳;即尽可能多的消息从发布到它们的同一个队列中消费,并且联邦机制只需要移动消息以执行负载均衡。

运行不同版本 RabbitMQ 的 Broker 可以使用联邦连接。

局限性

与非联邦对等方以及联邦交换机相比,联邦队列包含许多局限性或差异。

队列联邦不会将绑定从下游传播到上游。

使用 basic.get(通过轮询消费,一种极不推荐的做法)的应用程序如果本地队列中(客户端连接到的节点上)没有任何消息,则无法通过联邦检索消息。由于 basic.get 是一种同步方法,因此服务请求的节点必须在联系所有其他节点以检索更多消息时阻塞。这与联邦的面向可用性和分区容错的设计和用例不符。

用法和配置

联邦队列的声明方式与任何其他队列一样,由应用程序声明。为了使 RabbitMQ 识别出队列需要被联邦,以及应该从哪些其他节点消费消息,需要配置下游(消费)节点。

Federated queue policies

联邦配置使用运行时参数和策略,这意味着可以在系统拓扑更改时动态配置和重新配置它。涉及两个关键的配置部分

  • 上游:这些是联邦系统中的远程端点
  • 联邦策略:这些策略控制哪些队列是联邦的,以及它们将连接到哪些上游(对等方)

这两者都在下游节点或集群上配置。

要添加上游,请使用 rabbitmqctl set_parameter 命令。它接受三个参数

  • 参数类型,federation-upstream
  • 联邦策略将引用的上游名称
  • 上游定义 JSON 文档,其中至少包含一个强制性键,uri

以下示例配置了一个名为“origin”的上游,可以通过 remote-host.local:5672 联系到

# Adds a federation upstream named "origin"
rabbitmqctl set_parameter federation-upstream origin '{"uri":"amqp://remote-host.local:5672"}'

一旦指定了上游,就可以添加控制联邦的策略。它像任何其他策略一样添加,使用 rabbitmqctl set_policy

# Adds a policy named "queue-federation"
rabbitmqctl set_policy queue-federation "^federated\." \
'{"federation-upstream-set":"all"}' \
--priority 10 \
--apply-to queues

在上面的示例中,该策略将匹配默认虚拟主机中名称以 federated. 前缀开头的队列。这些队列将为所有声明的上游设置联邦链接。策略的名称是 queue-federation。与任何策略一样,如果多个策略匹配一个队列,则将使用优先级最高的策略。即使优先级相等,也不会组合多个策略定义。

配置完成后,将为每个匹配的队列和上游对打开一个联邦链接(连接)。这里“匹配的队列”是指与联邦策略模式匹配的队列。如果没有队列匹配,则不会启动任何链接。

要为匹配的队列停用联邦,请使用其名称删除策略

rabbitmqctl clear_policy queue-federation

复杂拓扑和循环处理

联邦队列可以是另一个联邦队列的“上游”。甚至可以形成“循环”,例如,队列 A 声明队列 B 是它的上游,队列 B 声明队列 A 是它的上游。允许多个连接的更复杂的安排。然而,这种复杂的拓扑将越来越难以推理和排除故障。

与联邦交换机不同,队列联邦不复制数据,也不显式处理循环。消息可以在联邦队列之间转发多少次没有限制。

在一组相互联邦的队列中,消息将移动到备用消费能力所在的位置,因此如果备用消费能力不断移动,那么消息也会如此。由于消息仅在没有本地消费者时才移动到远程节点,因此消息很少会跨所有节点移动并“环绕”。

实现

联邦队列将使用 AMQP 0-9-1(可选地使用 TLS 加密)连接到其所有上游队列。

联邦队列仅在本地消息耗尽、有消费者需要消息且上游队列有未被消费的“备用”消息时才检索消息。目的是确保仅在需要时才在联邦队列之间传输消息。这是使用消费者优先级实现的。

如果消息从一个队列转发到另一个队列,则只有在节点之间进行完全相同的旅程的消息才能保留消息顺序。在某些情况下,发布时相邻的消息可能会采用不同的路由到达同一节点进行消费;因此,在存在队列联邦的情况下,消息可能会被重新排序。

每个单独的队列都单独应用其参数;例如,如果您在联邦队列上设置 x-max-length,则该队列的长度将受到限制(可能会在队列满时丢弃消息),但与它联邦的其他队列将不受影响。特别注意,当使用每个队列或每个消息的 TTL 时,消息在传输到另一个队列时,其计时器将被重置。

陷阱

联邦队列目前无法仅根据一个地方对消息的需求而导致消息在 Broker 之间进行多次跳转。例如,如果您在节点 A、B 和 C 上联邦队列,其中 A 和 B 连接,B 和 C 连接,但 A 和 C 未连接,那么如果节点 A 上有消息可用,而节点 C 上有消费者等待,则消息将不会从 A 通过 B 传输到 C,除非节点 B 上也有消费者。

可以将联邦队列绑定到联邦交换机。但是,结果对于某些人来说可能是意想不到的。由于联邦交换机将从其上游检索与其绑定匹配的消息,因此发布到联邦交换机的任何消息都将被复制到任何具有匹配绑定的节点。然后,联邦队列将在节点之间移动这些消息,因此可能会在同一节点上最终得到同一消息的多个副本。

© . All rights reserved.