我在我的消费者中抛出一个AmqpException。 我的期望是该消息将以FIFO顺序返回队列,并在将来的某个时间进行重新处理。
似乎Spring AMQP不会将消息释放回队列。但是反而尝试一遍又一遍地重新处理失败的消息。 这会阻止处理新到达的消息。被卡住的那些永远出现在AMQP控制台内的“解包”状态。
有什么想法吗?
答案 0 :(得分:7)
这就像rabbitmq / Spring AMQP的工作方式;如果一条消息被拒绝(抛出任何异常),该消息将被默认重新排队,并被放回队列的头部,以便立即重试。
......将来某个时候再加工。
你必须适当地配置以实现这一目标。
首先,您必须告诉经纪人不要重新排队。这是通过将侦听器容器上的defaultRequeueRejected
设置为false(默认情况下为true)来完成的。或者,您可以抛出一个AmqpRejectAndDontRequeueException
来指示容器拒绝(而不是重新排队)单个消息。
但那不是结束;这样做只会导致被拒绝的消息被丢弃。
为避免这种情况,您必须为队列设置Dead Letter Exchange/Queue - 拒绝的消息然后被发送到DLX / DLQ而不是被丢弃。通常建议使用策略而不是队列参数。
最后,您可以设置在DLQ上生存的消息时间,这样,在此之后,消息将从队列中删除。如果您在 队列(DLQ)上设置另一个适当的死信交换,则可以使该消息在时间到期后重新排队回原始队列。
请注意,这仅适用于原始队列中拒绝的交付;当该队列中的消息过期时,它将无法工作。
有关详情,请参阅this answer及其问题中的部分链接。
你可以使用x-death
标题的内容来决定你是否应该在经过一些尝试后完全放弃(捕获异常并以某种方式处理坏消息;不要抛出异常并且容器会收到消息)。
答案 1 :(得分:1)
这是我用来解决这个问题的解决方案。我设置了一个拦截器,在应用退避策略时重试消息x次。 http://trippstech.blogspot.com/2016/03/rabbitmq-deadletter-queue-with.html