RabbitMQ 中的死信死信消息
Posted
技术标签:
【中文标题】RabbitMQ 中的死信死信消息【英文标题】:Dead-lettering dead-lettered messages in RabbitMQ 【发布时间】:2015-04-22 06:34:06 【问题描述】:这就是我们所拥有的:
主题交换DLE
,旨在进行死信交换
主题交流E
,这是“主要”交流
多个队列(EQ1
, ..., EQn
)绑定到E
(并使用x-dead-letter-exchange = DLE
初始化),每个队列都有自己的路由密钥。这些队列是从中消费的。
对于每个EQn
,都有一个DLEQn
(用x-dead-letter-exchange = E
和x-message-ttl = 5000
初始化)绑定到DLE
,并使用与EQn
相同的路由键。这些队列没有被消耗
我想要的是以下内容:如果消费者无法处理来自EQn
的消息,它会使用requeue: false
对消息进行Nacks,然后它会到达DLEQn
——也就是说,到达Dead 上的适当队列——信件交换。现在,我希望这条消息在DLEQn
上停留一段时间,然后被路由回原始队列EQn
以再次处理。
尽我所能,我无法让“重新传递到原始队列”工作。我看到消息位于 DLEQn
中,所有正确的标头和路由密钥都完好无损,但在 TTL 到期后,它们就消失了。
我在这里做错了什么?
【问题讨论】:
【参考方案1】:是的,您可以这样做。我们目前正在生产中这样做,效果很好。代码太长,无法在此处包含,但我将向您展示我创建的代表流程的图表。基本思想是第一个 DLX 有一个 TTL,一旦 TTL 过期,消息就会进入第二个队列,然后重新发送回原来的队列。
【讨论】:
如何重新发送到原始队列?是 RabbitMQ 重新发送还是重试队列上有单独的消费者? 一个单独的消费者从“重试重定向队列”中获取消息并查看兔子头。感兴趣的标题是“x-death”,里面有消息来自的交换和队列。我们使用它来将消息发送回许多不同的队列,这样我们只需要一个“重试重定向队列”。有意义吗? 像魅力一样工作!非常感谢。 @jhilden 您能否告诉您如何维护失败消息的计数。您是否使用了一些内置功能,或者您维护了自定义计数变量,并且每次重试时都会增加 自定义变量,这里是检查计数的代码:gist.github.com/jayhilden/2078872a53c7df0fe45d661861ed2d45【参考方案2】:RabbitMQ 检测消息流循环(E -> DLE -> E -> DLE ...)并静默丢弃消息:
来自DLX manual (Routing Dead-Lettered Messages section):
可以形成死信队列的循环。例如,当队列死信消息发送到默认交换时,可能会发生这种情况而没有指定死信路由键。如果整个周期是由于消息过期而导致的,那么此类周期中的消息(即两次到达同一队列的消息)将被丢弃。
【讨论】:
我想知道 RabbitMQ 3.1 (rabbitmq.com/release-notes/README-3.1.0.txt) 中的“25107 允许死信循环”是否真的允许它们。 我想在 RabbitMQ 用户组 (groups.google.com/forum/#!forum/rabbitmq-users) 中要求澄清会为这个问题带来一些启示。我不认为 25107 是您使用消息到期时的情况,这是根据 doc 丢弃消息的情况(我将那部分加粗) 好吧,我的周期完全不完全是因为到期了。 Nacking 原始消息将其从 E 移动到 DLE,然后 TTL 才起作用。不过,感谢您抽出宝贵时间!【参考方案3】:那篇帖子很老了,但我花了几天时间才找到类似问题的解决方案,所以我想我应该在这里分享我的解决方案。
我们在 TargetQueue 中接收消息(没有 TTL !!!,绑定到 TargetExchange),这些消息可能被消费者接收。 TargetQueue定义了一个DLX(RetryExchange),它又绑定了一个对应的队列(RetryQueue,TTL为60秒,TargetExchange定义为DLX)。
因此,如果消费者对来自 TargetQueue 的消息进行 nacks,它会在 RetryQueue 中排队,并且由于 TTL,消息会再次被 nacks 并重新排列在原始 TargetQueue 中。线索是,TargetQueue 可能没有定义 TTL,否则 RabbitMQ 日志中会出现这样的消息:
检测到死信队列循环:[>,>,>]
所以最终解决方案非常简单(并且只需要一个消费者)。最后的灵感来自https://medium.com/@igkuz/ruby-retry-scheduled-tasks-with-dead-letter-exchange-in-rabbitmq-9e38aa39089b
【讨论】:
以上是关于RabbitMQ 中的死信死信消息的主要内容,如果未能解决你的问题,请参考以下文章