rabbitmq - 工作队列提供延迟增加的重试和最大尝试次数。纯 RabbitMQ 解决方案是否可行?
问题描述
我有一些重复的任务,我想与许多工人一起处理(即竞争消费者模式)。任务期间失败的概率相当低,所以在这种罕见事件的情况下,我想在短时间内重试,比如 1 秒。
一系列连续失败的可能性更小,但仍有可能,因此对于一些初始重试,我想坚持 1 秒的延迟。
但是,如果故障序列达到某个点,那么很可能有一些外部原因可能导致这些故障。所以从那时起,我想开始延长延迟。
假设所需的延迟分布如下所示:
first appearance in the queue - no delay
retry 1 - 1 second
retry 2 - 1 second
retry 3 - 1 second
retry 4 - 5 second
retry 5 - 10 seconds
retry 6 - 20 seconds
retry 7 - 40 seconds
retry 8 - 80 seconds
retry 9 - 160 seconds
retry 10 - 320 seconds
another retry - drop the message
我找到了很多关于DLXes(Dead Letter Exchanges)的信息,可以部分解决问题。以相同的延迟实现无限次重试似乎很容易。同时,我还没有找到增加延迟或在重试一定次数后停止的方法。
我正在寻找最纯粹的 RabbitMQ 解决方案。但是,我对任何有效的东西都感兴趣。
解决方案
使用 DLX 和过期/TTL 时间的组合,您可以完成此操作,除非您想要更改重新传递时间,例如,实现指数退避。
我可以使用纯 RabbitMQ 方法使其工作的唯一方法是将过期时间设置为所需的最小时间,然后使用x-death数组来确定消息被杀死的次数然后拒绝(即 DLX再次)或相应地确认消息。
假设您将过期时间设置为 1 分钟,并且您需要第一次回退 1 分钟,然后是 5 分钟,然后是 30 分钟。这将转换为 x-death.count = 1,然后是 5,然后是 30。任何其他时间您只需拒绝该消息。
请注意,如果您有很多重试消息,这可能会造成大量流失。但是,如果重试很少见,那就去吧。
推荐阅读
- c - 当输出看起来正确时,为什么这种凯撒加密是错误的?
- java - Jpa 映射表未在约束错误时删除
- c++ - 如何检查数据包是否由于数据包碎片而被丢弃?
- postgresql - .net core heroku 应用程序中的“dotnet-ef 不存在”
- matlab - 如何使用作为 readtable 接收的数据作为 audioread 的输入?(MATLAB)
- c# - 如何使用值列表读取 appsettings.json?
- java - 需要您在 NoSQL 数据库方面的经验
- oracle - Kafka Connect - 原因:org.apache.kafka.connect.errors.ConnectException:表的 PK 模式为 RECORD_KEY,但缺少记录键模式
- html - 如何在 CSS 中更改表格?
- mysql - 哪个查询有更好的性能?