我正在使用rabbitmq上的死信交换功能来执行预定的rpc调用,但是在队列被删除后,它删除了原始队列中的replyto属性。无论如何,以一种它将保留在“死队列”中的方式声明replyto属性?
顺便说一下,我在node.js中使用amqplib这样做。
答案 0 :(得分:2)
不幸的是,RabbitMQ只会保留the Dead Letter Exchange page上列出的属性:
我认为,有两种方法可以解决您所看到的问题。
1)将回复放在你自己的标题或属性字段中,然后从那里读取它/当它不在通常的位置时替换它
2)不要使用回复字段。相反,在稍后的时间点使用一个众所周知的交换回复。
使用reply-to字段通常意味着请求/响应或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中还有更多信息(以及许多其他模式)。
希望有所帮助!