如何在以后重建被拒绝的消息,RabbitMQ

时间:2017-10-11 03:25:52

标签: java rabbitmq

有时由于某些外部问题,我需要使用requeue = true将basic.reject重新排队。

但我不需要立即消耗它,因为它可能会在短时间内再次失败。如果我不断重新排队,这可能会导致无限循环和重新排队。

  1. 所以我需要稍后消费,比如说一分钟后,

  2. 我需要知道消息被重新排队的次数,以便我可以停止重新排队,但只拒绝它以声明它无法消耗。

  3. PS:我正在使用Java客户端。

1 个答案:

答案 0 :(得分:0)

第1点有多种解决方案。

第一个是Celery选择的一个(Python生产者/消费者库,可以使用RabbitMQ作为代理)。在邮件中,添加应执行任务的时间戳。当您的消费者收到消息时,请不要确认消息并检查其时间戳。一旦达到时间戳,工作人员就可以执行任务。 (请注意,工人可以继续处理其他任务而不是等待) 这种技术有一些缺点。您必须将每个通道的QoS增加到任意值。如果您的工作人员已经在处理长时间运行的任务,则延迟任务将不会执行,直到第一个任务完成。

第二种技术仅限RabbitMQ,更加优雅。它利用了dead-letter exchangesMessages TTL。您创建一个任何人都不会消耗的新队列。此队列具有死信交换,将消息转发到使用者队列。当您想要延迟消息时,从消费者队列中确认消息(或者不经重新排队)并将消息复制到死信区队列中,其TTL等于您想要的延迟(比如一分钟后)。在(大致)TTL结束时,deferred消息将再次神奇地落入消费者队列中,准备好消费。 RabbitMQ团队也制作了Delayed Message Plugin(此插件标记为experimental yet fairly stable and potential suitable for production use as long as the user is aware of its limitations,并且在故障转移的情况下在可扩展性和可靠性方面存在严重限制,因此您可能决定是否确实要在生产中使用它,或者如果您更喜欢坚持手动方式,每个队列限制为一个TTL。

第2点。只需要在您的消息中放置一个计数器并在您的应用内处理它。您可以选择将此计数器放在标题中或直接放在正文中。