跳到主要内容
版本:4.1

备用交换器

概述

有时需要让客户端处理交换器无法路由的消息(即,因为没有绑定的队列或没有匹配的绑定)。典型的例子有:

  • 检测客户端何时意外或恶意发布无法路由的消息
  • “否则”路由语义,其中一些消息被特殊处理,其余的由通用处理程序处理

备用交换器(“AE”)是解决这些用例的功能。

如何定义备用交换器

对于除默认交换器之外的任何给定交换器,客户端可以使用策略来定义 AE。这是推荐的选项,因为策略显着简化了对此类选项的更改(例如,在升级期间)。

在现代 RabbitMQ 版本中,默认交换器是代码中特殊情况的约定,而不是“真实”的交换器。因此,它不支持备用交换器功能。

或者,客户端可以在交换器声明时提供可选的交换器参数。在策略和参数都指定 AE 的情况下,参数中指定的 AE 将覆盖策略中指定的 AE。

使用策略配置

这是定义备用交换器的推荐方式。

要使用策略指定 AE,请将键“alternate-exchange”添加到策略定义中,并确保该策略与需要定义 AE 的交换器匹配。例如

rabbitmqctl set_policy AE "^my-direct$" '{"alternate-exchange":"my-ae"}' --apply-to exchanges

这将把名为“my-ae”的 AE 应用于名为“my-direct”的交换器。也可以使用管理插件定义策略,有关更多详细信息,请参阅策略文档

使用客户端提供的参数进行配置

不鼓励使用这种定义备用交换器的方式。请考虑改用策略(见上文)。

创建交换器时,可以在exchange.declare方法的arguments表中可选地提供 AE 的名称,方法是指定键“alternate-exchange”和包含名称的字符串值。

当指定了 AE 时,除了对声明的交换器具有通常的configure权限外,用户还需要对该交换器具有read权限,并对 AE 具有write权限。

例如

Map<String, Object> args = new HashMap<String, Object>();
args.put("alternate-exchange", "my-ae");
channel.exchangeDeclare("my-direct", "direct", false, false, args);
channel.exchangeDeclare("my-ae", "fanout");
channel.queueDeclare("routed");
channel.queueBind("routed", "my-direct", "key1");
channel.queueDeclare("unrouted");
channel.queueBind("unrouted", "my-ae", "");

在上面的 Java 代码片段中,我们创建了一个直接交换器“my-direct”,它配置了一个名为“my-ae”的 AE。后者被声明为扇出交换器。我们将一个队列“routed”绑定到“my-direct”,绑定键为“key1”,并将一个队列“unrouted”绑定到“my-ae”。

备用交换器的工作原理

每当发布到配置了 AE 的交换器的消息无法路由到任何队列时,通道会将消息重新发布到指定的 AE。如果该 AE 不存在,则会记录警告。如果 AE 无法路由消息,它会反过来将消息发布到其 AE(如果已配置)。此过程将继续,直到消息成功路由、到达 AE 链的末尾,或者遇到已尝试路由消息的 AE。

例如,如果我们使用路由键“key1”将消息发布到“my-direct”,则该消息将根据标准的 AMQP 行为路由到“routed”队列。但是,当使用路由键“key2”将消息发布到“my-direct”时,该消息不会被丢弃,而是通过我们配置的 AE 路由到“unrouted”队列。

AE 的行为纯粹与路由有关。如果消息通过 AE 路由,它仍然算作已路由,用于“mandatory”标志,并且消息在其他方面保持不变。

© . All rights reserved.