延迟队列实现方案
2021-11-16 16:52:46 0 举报
AI智能生成
延迟队列实现方案
作者其他创作
大纲/内容
Redis 的 sorted set
描述
利用 Redis 的 sorted set 结构,使用 timeStamp 作为 score,比如你的任务是要延迟5分钟,那么就在当前时间上加5分钟作为 score ,轮询任务每秒只轮询 score 大于当前时间的 key即可,如果任务支持有误差,那么当没有扫描到有效数据的时候可以休眠对应时间再继续轮询。
优点
简单实用
缺点
单个 zset 肯定支持不了太大的数据量,如果你有几百万的延迟任务需求,大哥我还是劝你换一个方案;
定时器轮询方案可能会有异常终止的情况需要自己处理,同时消息处理失败的回滚方案,您也要自己处理。
定时器轮询方案可能会有异常终止的情况需要自己处理,同时消息处理失败的回滚方案,您也要自己处理。
RabbitMQ队列
描述
如果有事件需要延迟那么将该事件发送到MQ 队列中,为需要延迟的消息设置一个TTL;
TTL到期后就会自动进入设置好的DLX,然后由DLX转发到配置好的实际消费队列;
消费这个队列的延迟消息,处理事件。
TTL到期后就会自动进入设置好的DLX,然后由DLX转发到配置好的实际消费队列;
消费这个队列的延迟消息,处理事件。
优点
标准化支持。如果面临大数据量需求可以很容易的横向扩展,同时消息支持持久化,有问题可回滚
缺点
配置麻烦,额外增加一个死信交换机和一个死信队列的配置;
迁移很痛苦;
消息队列具有先进先出的特点,如果第一个进入队列的消息 A 的延迟是10分钟,第二个进入队列的消息B 的延迟是5分钟,期望的是谁先到 TTL谁先出,但是事实是B已经到期了,而还要等到 A 的延迟10分钟结束A先出之后,B 才能出。所以在设计的时候需要考虑不同延迟的消息要放到不同的队列。
迁移很痛苦;
消息队列具有先进先出的特点,如果第一个进入队列的消息 A 的延迟是10分钟,第二个进入队列的消息B 的延迟是5分钟,期望的是谁先到 TTL谁先出,但是事实是B已经到期了,而还要等到 A 的延迟10分钟结束A先出之后,B 才能出。所以在设计的时候需要考虑不同延迟的消息要放到不同的队列。
Netty#HashedWheelTimer
描述
Hash Wheel Timer是一个环形结构,可以想象成时钟,分为很多格子,一个格子代表一段时间(越短Timer精度越高),并用一个List保存在该格子上到期的所有任务。同时一个指针随着时间流逝一格一格转动,并执行对应List中所有到期的任务。
优点
实现比较优雅。效率高。
缺点
无法实现HA和横向扩展,要么就使用多个时间轮。
最重要的是,实现也比较复杂,开发者需要考虑所有可能的情况。
最重要的是,实现也比较复杂,开发者需要考虑所有可能的情况。
0 条评论
下一页