有时由于一些外部问题,我需要通过 basic.reject 并设置 requeue = true 重新排队消息。
但我不需要立即消耗它,因为它可能会在短时间内再次失败。如果我不断地重新排队,这可能会导致无限循环和重新排队。
所以我需要稍后再吃它,比如说一分钟后,
我需要知道消息已重新排队多少次,以便我可以停止重新排队,而只是拒绝它以声明它无法使用。
PS:我使用的是Java客户端。
最佳答案
第 1 点有多种解决方案。
第一个是 Celery 选择的(一个可以使用 RabbitMQ 作为代理的 Python 生产者/消费者库)。在消息中,添加应执行任务的时间戳。当您的消费者收到消息时,不要确认它并检查其时间戳。一旦达到时间戳,工作人员就可以执行任务。 (请注意,工作人员可以继续执行其他任务而不是等待)
这种技术有一些缺点。您必须将每个 channel 的 QoS 增加到任意值。如果您的工作人员已经在处理长时间运行的任务,则延迟的任务将在第一个任务完成之前不会执行。
第二种技术仅适用于 RabbitMQ,而且更加优雅。它利用dead-letter exchanges和 Messages TTL 。您创建了一个不被任何人使用的新队列。该队列有一个死信交换,它将消息转发到消费者队列。当您想要延迟消息时,从消费者队列中确认它(或拒绝它而不重新排队),并将消息复制到死信队列中,其 TTL 等于您想要的延迟(例如一分钟后)。在(大致)TTL 结束时,延迟的消息将神奇地再次进入消费者队列,准备被消费。 RabbitMQ 团队还制作了Delayed Message Plugin (此插件被标记为实验性但相当稳定,并且只要用户意识到其局限性,就可能适合生产使用
,并且在故障转移时的可扩展性和可靠性方面具有严重限制,因此您可以决定是否真的要在生产中使用它,或者如果您更喜欢坚持手动方式,每个队列仅限一个 TTL)。
第 2 点只需要在您的消息中放置一个计数器并在您的应用程序中处理它。您可以选择将此计数器放在标题中或直接放在正文中。
关于java - 如何稍后重新使用被拒绝的消息,RabbitMQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46679275/