无论如何要防止 rabbitmq 死信队列丢弃属性?

Anyway to prevent rabbitmq dead letter queue dropping properties?

我正在使用 rabbitmq 上的死信交换功能来执行计划的 rpc 调用,但是在队列被死信后,它丢弃了原始队列中的回复 属性。无论如何,是否可以以一种将保留在 "dead queue" 中的方式声明对 属性 的回复?

顺便说一下,我在 node.js 中用 amqplib 来做这个。

不幸的是,RabbitMQ 只会保留 the Dead Letter Exchange page:

中列出的属性
  • queue - 消息在 dead-lettered、
  • 之前所在的 queue 的名称
  • 原因 - 使用 DLX 的原因
  • time - 消息被死信化为 64 位 AMQP 格式时间戳的日期和时间,
  • exchange - 消息发布到的交换
  • routing-keys - 发布消息的路由键,
  • count - 由于这个原因,此消息在 queue 中 dead-lettered 的次数,以及
  • original-expiration - 消息的原始到期时间 属性。

我认为有 2 种方法可以解决您遇到的问题。

1) 将 reply-to 放在你自己的 header 或 属性 字段中,然后从那里读取它/当它不在通常位置时替换它

2) 不要使用 reply-to 字段。相反,请在稍后的某个时间点使用 well-known 交换来获取回复。

使用 reply-to 字段通常意味着 request/response 或 RPC 场景。这些场景通常需要相当快的响应。如果响应没有很快到来,系统通常可以在没有它的情况下继续前进——即使它只是给用户的一条消息说 "X is not available right now"。

您说您正在使用 DLX 执行计划的 RPC 调用...延迟消息是 DLX 的常见用例 - 这没什么问题。但是延迟 RPC 响应可能 运行 会遇到一些您已经看到的重大挑战。

例如,当您的系统出现故障并且发出原始请求的代码不再用于侦听响应时会发生什么情况?这个问题的答案取决于您是否真的需要处理响应。如果您确实需要处理它 - 如果不需要,系统将 运行 陷入严重的麻烦 - 那么 RPC 可能很危险。

与其依赖 RPC 并暗示对给定响应的时间需求,不如通过单独的 queue 使用 two-way 消息传递更好。我在我的 managing long running processes post and in my RabbitMQ Patterns 电子邮件课程/电子书中都写过这个。

其要点是,您可以通过让原始消息发布者同时也是具有 queue 响应的订阅者来避免 reply-to queue 的需要。

长 运行ning 过程中的示例 post:


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);
  }
};

在此示例中,代码发送 "request" 并稍后接收 "response" - 但未使用标准 RPC 设置。它使用专用的 queue 作为响应,另一端的代码通过路由到 queue 的交换发送回回复。

这使您可以更好地处理故障情况、非常长的 运行ning 进程等等。

不过,这种双向消息传递方式确实增加了一些额外的挑战。首先,您必须构建重建发出原始请求的 object 的能力。

您也可以在 the long running process post, and there's a bit more info in RMQ Patterns 中找到详细信息(以及许多其他模式)。

希望对您有所帮助!