处理RabbitMQ中的死信

16
TL;DR: 我需要将死信消息“重放”到它们原始的队列中,一旦我修复了最初导致消息被拒绝的消费者代码。我已经为RabbitMQ配置了Dead Letter Exchange(DLX),并成功地将被拒绝的消息路由到死信队列。但现在我想查看死信队列中的消息,并尝试决定如何处理每个消息。其中一些(很多?)消息应该在有了修复有问题的消费者代码之后重新放入它们原来的队列(可以在“x-death”头中找到)。但是我应该怎么做呢?我应该编写一个读取死信队列中的消息,并允许我指定要发送到的目标队列的单次性程序吗?至于搜索死信队列呢?如果我知道某个消息(比如说编码为JSON的消息)有一个我想要搜索和重放的特定属性怎么办?例如,我修复了一个缺陷,我知道现在会成功处理PacketId:1234的消息。我也可以为此编写一个一次性程序。我肯定不是第一个遇到这些问题的人,我想知道是否有其他人已经解决了这些问题。似乎应该有某种瑞士军刀适用于这种事情。我在Google和Stack Overflow上进行了相当广泛的搜索,但并没有真正找到什么。我找到的最接近的东西是铲子,但那似乎不是正确的工具。
1个回答

10

我应该编写一个一次性程序,从死信队列中读取消息,并允许我指定要发送到的目标队列吗?

总体而言,是的。

您可以使用延迟消息交换插件组合设置延迟重试,将消息重新发送回原始队列。

但这只会在时间间隔上自动化重试,并且可能在重试发生之前未解决问题。

在某些情况下,这是可以接受的 - 比如当错误是由外部资源暂时不可用引起的。

在您的情况下,我认为创建处理死信的应用程序是最好的方法,有几个原因:

  • 您需要搜索消息,而RMQ无法实现此功能
  • 这意味着您需要一个数据库来存储DLX /队列中的消息

因为您正在从DLX /队列中提取消息,所以您需要确保获得消息的所有标头信息,以便在适当时重新发布到正确的队列。

我肯定不是第一个遇到这些问题的人,想知道是否有其他人已经解决了它们。

您不是第一个遇到这个问题的人!

有许多解决此问题的解决方案,最终都归结为您提出的解决方案。

一些较大的“服务总线”实现已经内置了此类功能。例如,我认为NServiceBus(或其SaaS版本)已经内置了此功能-尽管我不能100%确定。

如果您想进一步了解此问题,请搜索“毒消息”一词-通常用于描述此情况。我在Google上进行了快速搜索,发现了一些可能有助于您解决问题的内容:

希望这些链接能对您有所帮助!


1
我并没有觉得这些链接特别有用,但是我非常感谢你详尽的回答。谢谢! - Dan
是的,我真的没有读那些链接。我只是想快速找到一些可能有用的东西。在发布它们之前应该先读一下它们。:P - Derick Bailey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接