我们已经将队列配置为将死信消息(特别是 nack'ed 消息)发送到死信交换,该死信交换按其原始主题将它们路由到各个死信队列。这一切都很有效,当消息被拒绝时,它们会被发送到正确的死信队列。
当我们将这些消息从 dlq 铲回到普通队列时,问题就来了,在那里它们再次被拒绝。由于某种原因,第二次它们只是消失了,而不是被送回死信交换。
我假设正在进行某种“循环消息路由”检测,但找不到类似的东西。第二次检查消息会给出所有预期的 header ,因此我不确定这样的事情是基于什么。任何有关下一步该去哪里或者兔子是否有这样的东西的建议将不胜感激!
如果有必要,我们的消费者是用 python 编写的,使用 pika 库进行通信。
最佳答案
假设您有以下队列/交换器:
交流
global_exchange
- 您的主要交易所DLX
- 另一种专门针对死信的交换
队列
queue
-global_exchange
中的主队列。包含arguments=x-dead-letter-exchange: 'DLX'
queue.dlq
-global_exchange
中的死信队列
绑定(bind)
test_message
routing_key 绑定(bind)到queue
和queue.dlq
最后,我假设您正在使用 queue.dlq
管理页面上的 shovel 插件,将消息从 queue.dlq
移动到 queue
:
以下是当您将 test_message
作为 routing_key
发送到 global_exchange
的消息时路由的工作原理:
- 消息通过
test_message
上的绑定(bind)进入queue
- 消费者 nack(nack 或拒绝无关紧要)消息,从而将其置为死信
x-dead-letter-exchange
参数通过routing_key= test_message
将其发送到DLX
- 由于
queue.dlq
绑定(bind),该队列接收消息
当您使用该特定管理面板将消息铲回队列
时,它会使用default exchange 。这更改路由键。因此,第二次收到的消息的路由键等于您要放入的队列的名称。
由于您没有配置 x-dead-letter-routing-key
,因此该消息将死信发送至 current routing key :
If this is not set, the message's own routing keys will be used.
因此,根据铲子的结果,它的路由方式如下:
- 消息出现在
queue
中,且routing_key = queue
- 由于没有配置 x-dead-letter-routing-key,因此它会通过
routing_key = queue
向DLX
发送死信 - 没有绑定(bind)到
DLX
中的队列
,消息被丢弃
有 2 个潜在的解决方法:
- 将
queue.dlq
的另一个绑定(bind)添加到routing_key = queue
- 手动配置
队列
上的x-dead-letter-routing-key
,以始终发送到死信上的相同路由键,无论最初发送什么消息并确保在DLX
中对其进行绑定(bind)
关于RabbitMQ 消息第一次发送后未发送至死信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63235721/