背景
我们正在使用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)?
答案 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退出该队列并进入另一个队列,将其放回原始队列
设置需要一些工作,但效果很好!