指示RabbitMQ定期重新发送未传递的消息

时间:2016-01-03 14:50:32

标签: rabbitmq spring-amqp spring-rabbit spring-rabbitmq langohr

背景

我们正在使用langohr与RabbitMQ进行交互。我们尝试了两种不同的方法让RabbitMQ重新发送尚未由我们的服务正确处理的消息。一种方法是将basic.nack requeue设置发送到true,但这会立即重新发送消息,直到服务以basic.ack响应。如果服务例如尝试将消息持久保存到当前已关闭的数据存储(并且暂停一段时间),则这有点问题。如果数据存储区已关闭,我们最好每隔20秒左右获取未传递的消息(即我们既没有basic.ack也不basic.nack,我们只是将消息保留在队列)。我们尝试使用ExecutorService来实现这一点,{g}的实现方式如下:

(let [chan (lch/open conn)]  ; We create a new channel since channels in Langohr are not thread-safe
    (log/info "Triggering \"recover\" for channel" chan)
    (try
      (lb/recover chan)
      (catch Exception e (log/error "Failed to call recover" e))
      (finally (lch/close chan))))

不幸的是,这似乎不起作用(消息不会重新传递,只是保留在队列中)。如果我们重新启动服务,则会正确使用排队的消息。但是我们有其他使用spring-rabbitmq(在Java中)实现的服务,他们似乎正在开箱即用。我已经尝试查看source code以了解他们是如何做到的,但我还没有设法这样做。

问题

如何指示RabbitMQ定期(重新)在队列中传递消息(最好使用Langohr)?

2 个答案:

答案 0 :(得分:1)

我不确定您在使用Spring AMQP应用程序时做了什么,但RabbitMQ没有内置任何内容。

然而,使用TTL设置死字法很容易在一段时间后重新排队回原始队列。有关示例,链接等,请参阅this answer

修改

但是,Spring AMQP 确实retry interceptor which can be configured to suspend the consumer thread for some period(s) during retry

有状态重试拒绝并重新排队;无状态重试在内部处理重试,并且在重试期间没有与代理交互。

答案 1 :(得分:1)

请参阅this answer,其中有说明:我们Nack消息,nack将消息放入保留队列N秒,然后TTL退出该队列并进入另一个队列,将其放回原始队列

设置需要一些工作,但效果很好!