从一个队列铲到另一个队列后如何拒绝消息?

时间:2018-04-30 06:48:39

标签: java rabbitmq spring-rabbitmq dead-letter rabbitmq-shovel

使用Spring和RabbitMQ,我设置了两个主题交换<html lang="ja"> <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script> <head> <meta charset="UTF-8"> <title>HOMEPAGE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> nav { width: 312px; height: 100%; transition: all 0.2s; transform: translate(312px); position: fixed; top: 0; right: 0; z-index: 1000; background-color: #FFF; } nav.open { transform: translate(0); } </style> </head> <script> $(function(){ $('.btn_menu').click(function(){ $(this).next('nav').toggleClass('open'); }); }) </script> <body> <section id="center"> <button type="button" class="btn_menu"> AAA </button> <button type="button" class="btn_menu"> BBB </button> <button type="button" class="btn_menu"> CCC </button> </section> <nav> <h2>HOMEPAGE</h2> <!---->   <h4>AAA</h4>   <p>aaa</p> <!---->   <h4>BBB</h4>   <p>bbb</p> <!---->   <h4>CCC</h4>   <p>ccc</p> <!----> </nav> </body> </html> x以及两个队列dlxqdlq绑定到qxdlqdlx被配置为dlx的死信交换。

如果q中的邮件被拒绝(带有非排队),则会成功发送至q,然后发送至dlx

现在我使用shovel-plugin将dlq中的死信消息移回dlq。只要此次成功处理消息(ack),这就可以成功运行。

但是,如果q中的其中一条被铲除的消息再次被拒绝,则会被静默删除。我希望它再次发送到DLX q。我是否配置了错误或者是否误解了DLX或铲子的概念?

2 个答案:

答案 0 :(得分:1)

我怀疑你正在尝试这种......

  

可以形成消息死字的循环。例如,当队列在没有指定死信路由密钥的情况下将消息写入默认交换时,就会发生这种情况。如果在整个周期中没有拒绝,那么这些周期中的消息(即两次到达同一队列的消息)将被丢弃。

...因为你在铲。请参阅Dead Letter Exchanges

相反,请使用TTL配置DLQ,并使用死信配置将导致过期的消息路由回原始队列。这样,x-death标头获得两个条目 - 1个用于原始队列的拒绝,1个用于DLQ的到期。

我猜测,通过挖掘,经纪人认为有一个循环。

答案 1 :(得分:0)

我认为您的问题不是周期。假设您正在使用Rabbit管理GUI中的shovel插件,这将更改邮件的路由键,以显式使用“默认交换”上队列的路由键。

https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default

默认交换是经纪人预先声明的不带名称(空字符串)的直接交换。它具有一个特殊的属性,使其对于简单的应用程序非常有用:每个创建的队列都使用与队列名称相同的路由键自动绑定到该队列。

根据上面的示例,我假设您具有以下设置:

  • q自变量-x-dead-letter-exchange = dlx
  • q绑定:test_message
  • dlq绑定:test_message

因此,如果您使用x的路由密钥向test_message发送消息,则路由方式如下:

  1. 出现在q
  2. q中的消费者获取消息,发送nack,然后通过路由键dlx发送到test_message
  3. dlx已将dlq配置为绑定到test_message路由密钥,因此消息出现在dlq

现在,当您使用dlq中的铲子插件将所有邮件移动到q中时,就像这样:

enter image description here

然后,这会将消息发送到exchange = ''routing_key = 'q'。同样在https://www.rabbitmq.com/dlx.html#using-optional-queue-arguments中指出:

如果未设置,则将使用邮件自己的路由键。

所以现在发生了什么

  1. 消息以q出现在routing_key = q
  2. 由于未配置x-dead-letter-routing-key,因此使用routing_key dlxq的空字母
  3. dlx中没有绑定q,消息已删除

2个潜在的解决方法:

  1. dlqrouting_key = q添加另一个绑定
  2. 手动配置x-dead-letter-routing-key队列上的q,使其始终发送到死信上的同一路由密钥