从一个队列铲到另一个队列后如何拒绝消息?
How to reject messages after shoveling from one queue to another?
使用 Spring 和 RabbitMQ,我设置了两个主题交换 x
和 dlx
以及两个队列 q
和 dlq
。 q
绑定到 x
,dlq
绑定到 dlx
。 dlx
配置为 q
.
的死信交换
当 q
中的消息被拒绝(取消排队)时,它会成功发送到 dlx
,然后发送到 dlq
。
现在我使用 shovel-plugin 将 dlq
中的死信消息移回 q
。只要这次成功处理消息 (ack),此操作就会成功。
但是,如果 q
中的这些被铲除的消息之一再次被拒绝,它将被静默丢弃。我希望它再次发送到 DLX dlx
。是我配置有误还是我误解了 DLX 或铲子的概念?
我怀疑你正在尝试这个......
It is possible to form a cycle of message dead-lettering. For instance, this can happen when a queue dead-letters messages to the default exchange without specifiying a dead-letter routing key. Messages in such cycles (i.e. messages that reach the same queue twice) will be dropped if there was no rejections in the entire cycle.
...因为你在铲土。参见 Dead Letter Exchanges。
相反,使用 TTL 配置 DLQ,并且 dead-letter 配置导致过期消息被路由回原始 queue。这样,x-death
header 得到两个条目 - 1 个用于原始 queue 的拒绝,1 个用于 DLQ 的到期。
我猜想,有铲,经纪人认为有一个周期。
我不认为你的问题是循环。假设您正在使用 Rabbit 管理 GUI 中的 shovel 插件,这会更改消息的路由键以显式使用 'Default Exchange'
上队列的路由键
https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default
The default exchange is a direct exchange with no name (empty string) pre-declared by the broker. It has one special property that makes it very useful for simple applications: every queue that is created is automatically bound to it with a routing key which is the same as the queue name.
根据你上面的例子,我假设你有这些设置:
q
个参数 - x-dead-letter-exchange = dlx
q
绑定:test_message
dlq
绑定:test_message
因此,如果您使用 test_message
的路由键向 x
发送消息,则消息的路由方式如下:
- 出现在
q
q
中的消费者获取消息,发送 nack,它使用路由密钥 test_message
发送到 dlx
dlx
将 dlq
配置为绑定到 test_message
路由键,因此消息出现在 dlq
现在,当您使用 dlq
中的铲子插件将所有消息移动到 q
时,如下所示:
然后这会向 exchange = ''
和 routing_key = 'q'
发送一条消息。同样来自 https://www.rabbitmq.com/dlx.html#using-optional-queue-arguments 它指出:
If this is not set, the message's own routing keys will be used.
现在是这样:
- 消息出现在
q
中 routing_key = q
- 由于没有配置
x-dead-letter-routing-key
,它死信给dlx
和routing_key q
dlx
中没有绑定到 q,消息已丢弃
2 个潜在修复:
- 将
dlq
的另一个绑定添加到 routing_key = q
- 手动配置
q
队列上的 x-dead-letter-routing-key
始终发送到 dead-letter 上的相同路由键
使用 Spring 和 RabbitMQ,我设置了两个主题交换 x
和 dlx
以及两个队列 q
和 dlq
。 q
绑定到 x
,dlq
绑定到 dlx
。 dlx
配置为 q
.
当 q
中的消息被拒绝(取消排队)时,它会成功发送到 dlx
,然后发送到 dlq
。
现在我使用 shovel-plugin 将 dlq
中的死信消息移回 q
。只要这次成功处理消息 (ack),此操作就会成功。
但是,如果 q
中的这些被铲除的消息之一再次被拒绝,它将被静默丢弃。我希望它再次发送到 DLX dlx
。是我配置有误还是我误解了 DLX 或铲子的概念?
我怀疑你正在尝试这个......
It is possible to form a cycle of message dead-lettering. For instance, this can happen when a queue dead-letters messages to the default exchange without specifiying a dead-letter routing key. Messages in such cycles (i.e. messages that reach the same queue twice) will be dropped if there was no rejections in the entire cycle.
...因为你在铲土。参见 Dead Letter Exchanges。
相反,使用 TTL 配置 DLQ,并且 dead-letter 配置导致过期消息被路由回原始 queue。这样,x-death
header 得到两个条目 - 1 个用于原始 queue 的拒绝,1 个用于 DLQ 的到期。
我猜想,有铲,经纪人认为有一个周期。
我不认为你的问题是循环。假设您正在使用 Rabbit 管理 GUI 中的 shovel 插件,这会更改消息的路由键以显式使用 'Default Exchange'
上队列的路由键https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default
The default exchange is a direct exchange with no name (empty string) pre-declared by the broker. It has one special property that makes it very useful for simple applications: every queue that is created is automatically bound to it with a routing key which is the same as the queue name.
根据你上面的例子,我假设你有这些设置:
q
个参数 -x-dead-letter-exchange = dlx
q
绑定:test_message
dlq
绑定:test_message
因此,如果您使用 test_message
的路由键向 x
发送消息,则消息的路由方式如下:
- 出现在
q
q
中的消费者获取消息,发送 nack,它使用路由密钥test_message
发送到 dlx
将dlq
配置为绑定到test_message
路由键,因此消息出现在dlq
dlx
现在,当您使用 dlq
中的铲子插件将所有消息移动到 q
时,如下所示:
然后这会向 exchange = ''
和 routing_key = 'q'
发送一条消息。同样来自 https://www.rabbitmq.com/dlx.html#using-optional-queue-arguments 它指出:
If this is not set, the message's own routing keys will be used.
现在是这样:
- 消息出现在
q
中routing_key = q
- 由于没有配置
x-dead-letter-routing-key
,它死信给dlx
和routing_keyq
dlx
中没有绑定到 q,消息已丢弃
2 个潜在修复:
- 将
dlq
的另一个绑定添加到routing_key = q
- 手动配置
q
队列上的x-dead-letter-routing-key
始终发送到 dead-letter 上的相同路由键