【发布时间】:2015-08-11 20:42:32
【问题描述】:
我正在使用 rabbitmq 上的死信交换功能来执行预定的 rpc 调用,但是在队列死信后,它丢弃了原始队列中的回复属性。无论如何声明replyto属性以将其保留在“死队列”中?
顺便说一句,我正在使用 node.js 中的 amqplib 来执行此操作。
【问题讨论】:
标签: javascript rabbitmq
我正在使用 rabbitmq 上的死信交换功能来执行预定的 rpc 调用,但是在队列死信后,它丢弃了原始队列中的回复属性。无论如何声明replyto属性以将其保留在“死队列”中?
顺便说一句,我正在使用 node.js 中的 amqplib 来执行此操作。
【问题讨论】:
标签: javascript rabbitmq
很遗憾,RabbitMQ 只会保留the Dead Letter Exchange page 上列出的属性:
我认为有两种方法可以解决您遇到的问题。
1) 将回复放在您自己的标题或属性字段中,然后从那里读取/当它不在通常位置时替换它
2) 不要使用回复字段。相反,在稍后的时间点使用众所周知的交换来回复。
使用回复字段通常意味着请求/响应或 RPC 场景。这些情况通常需要相当快的响应。如果没有快速响应,系统通常可以在没有它的情况下继续前进——即使它只是给用户的一条消息,说“X 现在不可用”。
您说您正在使用 DLX 进行预定的 RPC 调用...延迟消息是 DLX 的常见用例 - 这没有错。但是延迟 RPC 响应可能会遇到一些超出您已经看到的重大挑战。
例如,当您的系统出现故障并且发出原始请求的代码不再用于侦听响应时会发生什么?这个问题的答案取决于您是否真的需要处理响应。如果您确实需要处理它 - 如果不需要,系统会遇到严重的问题 - 那么 RPC 可能很危险。
与其依赖 RPC 并暗示对给定响应的临时需求,不如通过单独的队列使用双向消息传递。我在managing long running processes 帖子和RabbitMQ Patterns 电子邮件课程/电子书中都写过这个。
它的要点是,您可以通过让原始消息发布者也成为具有响应队列的订阅者来避免需要回复队列。
来自长期运行过程帖子的示例:
var DrinkRequestSender = new Sender(/* ... details ... */);
var DrinkRequestReceiver = new Receiver(/* ... details ... */);
var DrinkStation = {
make: function(drink){
DrinkRequestReceiver.receive((response) => {
var drinkResponse = response.body;
this.trigger("drinkup", drinkResponse);
});
var drinkData = drink.toJSON();
DrinkRequestSender.send(drinkData);
}
};
在此示例中,代码发送“请求”,然后接收“响应” - 但未使用标准 RPC 设置。它使用专用队列进行响应,另一端的代码通过路由到该队列的交换发送回响应。
这使您可以更好地处理故障情况、运行时间很长的进程等等。
不过,这种双向消息传递方式确实增加了一些额外的挑战。一方面,您必须具备重建发出原始请求的对象的能力。
您可以在 the long running process post 中找到详细信息,RMQ Patterns 中还有更多信息(以及许多其他模式)。
希望有帮助!
【讨论】: