跳至主要内容
版本:4.0

直接回复

概述

直接回复是一个允许 RPC(请求/回复)客户端(其设计类似于教程 6中演示的设计)避免为每个请求声明一个回复队列的功能。

动机

RPC(请求/回复)是一种使用消息代理(如 RabbitMQ)实现的流行模式。教程 6演示了它与各种客户端的实现。典型的方法是,RPC 客户端发送路由到长期存在的(已知)服务器队列的请求。RPC 服务器从该队列中消费请求,然后使用客户端在reply-to标头中命名的队列向每个客户端发送回复。

客户端的队列来自哪里?客户端可以为每个请求-响应对声明一个单次使用的队列。但这效率低下;即使是短暂的非复制队列,创建和删除的成本也可能很高(与发送消息的成本相比)。这在集群中尤其如此,因为所有集群节点都需要同意队列已创建,同意其类型、复制参数和其他元数据。

因此,或者客户端可以为其回复创建一个长期存在的队列。但这可能难以管理,尤其是在客户端本身不是长期存在的情况下。

直接回复功能允许 RPC 客户端直接从其 RPC 服务器接收回复,而无需通过回复队列。“直接”在这里仍然意味着通过相同的连接和 RabbitMQ 节点;RPC 客户端和 RPC 服务器进程之间没有直接的网络连接。

如何使用直接回复

要使用直接回复,RPC 客户端应

  • 以无确认模式从伪队列amq.rabbitmq.reply-to消费。无需首先声明此“队列”,尽管客户端可以这样做(如果需要)。

  • 将其请求消息中的reply-to属性设置为amq.rabbitmq.reply-to

然后,RPC 服务器将看到一个带有生成名称的reply-to属性。它应该发布到默认交换机(""),并将路由键设置为此值(即,就像通常发送到回复队列一样)。然后,消息将直接发送到客户端消费者。

如果 RPC 服务器要执行一些昂贵的计算,它可能希望检查客户端是否已断开连接。为此,服务器可以在可丢弃的通道上首先声明生成的回复名称,以确定它是否仍然存在。请注意,即使您使用passive=false声明“队列”,也无法创建它;声明只会成功(有 0 条消息准备就绪和 1 个消费者)或失败。

注意事项和限制

  • RPC 客户端必须在自动确认模式下消费。这是因为如果没有队列来返回回复消息,则客户端断开连接或拒绝回复消息。

  • RPC 客户端必须对从amq.rabbitmq.reply-to消费和发布请求消息都使用相同的连接和通道。

  • 使用此机制发送的回复消息通常不是容错的;如果发布原始请求的客户端随后断开连接,它们将被丢弃。假设在这种情况下,RPC 客户端将重新连接并提交另一个请求。

  • 名称amq.rabbitmq.reply-tobasic.consumereply-to属性中被用作队列;但是它不是。它不能被删除,并且不会出现在管理插件或rabbitmqctl list_queues中。

  • 如果 RPC 服务器在设置了强制标志的情况下发布,则amq.rabbitmq.reply-to.*将被视为不是队列;即,如果服务器仅发布到此名称,则消息将被视为“未路由”;如果设置了强制标志,则将发送basic.return

© 2024 RabbitMQ. All rights reserved.