使用者关闭时,消息未路由到死信队列

时间:2018-11-29 17:28:36

标签: rabbitmq spring-amqp

我有一个服务A,它将消息发布到Queue(Q-A)。 我有一个用DLRK绑定到DLX的死信队列(DLQ)。 队列A通过路由键(RA)绑定到交换机(E-A)。 我还将Q-A上的x字母交换(DLX)和x-dead-letter-routing-key(DLRK)设置为60秒,此队列上的ttl-per-message DLQ还通过x-letter-exchange(E-A)和x-dead-letter-routing-key(DLRK)以及此消息上的ttl-per-message设置为60秒。

使用上述配置,我试图在ttl到期后将消息从Q-A路由到DLQ,反之亦然。 在作为另一项服务的使用者方面,我抛出了AMQPRejectAndDontRequeueException,并将defaultRequeueRejected设置为fals。

当使用者启动并抛出
时,上述配置可以正常工作
例外。 但是我试图将队列大小限制为1,然后向Q-A发布3条消息,并关闭使用者。我看到所有三个消息都放置在Q-A和DLQ中,最终所有消息都被丢弃。 但是,如果我没有将队列限制设置为1或启动使用者,则一切正常。

我还将x溢出设置为拒绝发布,当溢出时,我在发布者面前遇到了麻烦,然后我有了一个调度程序,将其再次发布到了Q-A。

注意:两种交换都是直接交换,我正在使用路由键将其绑定到各自的队列。

请告诉我是否在这里丢失了一些东西,并告诉我需要共享我的配置

2 个答案:

答案 0 :(得分:0)

深入研究之后,我认为我终于从链接Dead-lettering dead-lettered messages in RabbitMQ中找到了答案 品尼平回答

  

可能会形成死信队列的循环。例如,当队列将邮件死信到默认交换而不指定死信路由键时,可能会发生这种情况。如果整个周期是由于消息到期,则处于这种周期的消息(即两次到达同一队列的消息)将被丢弃。

因此,我想解决该问题,我需要创建另一个使用者以从死信队列中使用,并将其从该使用者发布回原始队列,而不是直接从死信队列中返回ttl。如果我的理解正确,请纠正我。

答案 1 :(得分:0)

我可能为时已晚,但是我想可以为您提供帮助。

故事: 您希望重试队列在一定时间后将死消息发送到主队列,并在主队列中检索并重新排队它们。

解决方案:

  1. 声明您的主队列并将其绑定到交换。我们将它们称为main_queuemain_exchange,并将此功能添加到main_queue中:x-dead-letter-exchange: retry_exchange
  2. 创建重试队列并将其绑定到另一个交换。我们将它们称为retry_queueretry_exchange,并将这些功能添加到重试队列中:x-dead-letter-exchange: main_exchangex-message-ttl: 10000

通过这种组合,来自main_queue的无效消息将被发送到retry_queue,并在10秒钟后将它们再次发送到main_queue,它们将无限期地持续直到消费者声明它们为止死了。

注意:仅当您将消息发布到交易所而不是直接在队列中时,此方法才有效。