RabbitMQ 消息第一次发送后未发送至死信

标签 rabbitmq pika rabbitmq-exchange rabbitmq-shovel

我们已经将队列配置为将死信消息(特别是 nack'ed 消息)发送到死信交换,该死信交换按其原始主题将它们路由到各个死信队列。这一切都很有效,当消息被拒绝时,它们会被发送到正确的死信队列。

当我们将这些消息从 dlq 铲回到普通队列时,问题就来了,在那里它们再次被拒绝。由于某种原因,第二次它们只是消失了,而不是被送回死信交换。

我假设正在进行某种“循环消息路由”检测,但找不到类似的东西。第二次检查消息会给出所有预期的 header ,因此我不确定这样的事情是基于什么。任何有关下一步该去哪里或者兔子是否有这样的东西的建议将不胜感激!

如果有必要,我们的消费者是用 python 编写的,使用 pika 库进行通信。

最佳答案

假设您有以下队列/交换器:

交流

  • global_exchange - 您的主要交易所
  • DLX - 另一种专门针对死信的交换

队列

  • queue - global_exchange 中的主队列。包含 arguments=x-dead-letter-exchange: 'DLX'
  • queue.dlq - global_exchange 中的死信队列

绑定(bind)

  • test_messagerouting_key 绑定(bind)到 queuequeue.dlq

最后,我假设您正在使用 queue.dlq 管理页面上的 shovel 插件,将消息从 queue.dlq 移动到 queue :

enter image description here

以下是当您将 test_message 作为 routing_key 发送到 global_exchange 的消息时路由的工作原理:

  1. 消息通过 test_message 上的绑定(bind)进入 queue
  2. 消费者 nack(nack 或拒绝无关紧要)消息,从而将其置为死信
  3. x-dead-letter-exchange 参数通过 routing_key= test_message 将其发送到 DLX
  4. 由于 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.

因此,根据铲子的结果,它的路由方式如下:

  1. 消息出现在 queue 中,且 routing_key = queue
  2. 由于没有配置 x-dead-letter-routing-key,因此它会通过 routing_key = queueDLX 发送死信
  3. 没有绑定(bind)到 DLX 中的队列,消息被丢弃

有 2 个潜在的解决方法:

  1. queue.dlq 的另一个绑定(bind)添加到 routing_key = queue
  2. 手动配置队列上的x-dead-letter-routing-key,以始终发送到死信上的相同路由键,无论最初发送什么消息并确保在 DLX
  3. 中对其进行绑定(bind)

关于RabbitMQ 消息第一次发送后未发送至死信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63235721/

相关文章:

rabbitmq - 鼠兔 + RabbitMQ : setting basic_qos to prefetch=1 still appears to consume all messages in the queue

python - 使用 RabbitMQ - 多个生产者和多个消费者

php - Laravel Queue Worker、RabbitMQ 和远程生成的运行作业

java - 根据 en 值在 Spring Boot 中加载 Rabbit 或 IBM mq 配置

.net - 如何检查RabbitMQ消息队列是否存在?

python - 如何将 Pika 与 Qt 集成?

c# - Xamarin 中的 RabbitMQ

python - 可以在网络应用程序中使用 Pika BlockingConnection 吗?

rabbitmq - 同一交货标签的多次确认

rabbitmq - 是否可以在交换中缓冲消息,直到至少有一个队列可用?