如何用JAVA编程实现一个延迟队列的功能?
- 内容介绍
- 相关推荐
本文共计2554个文字,预计阅读时间需要11分钟。
延迟队列的需求各位置应日常开发场景中经常遇到。例如:- 用户登录后5分钟内进行分类推送;- 用户多天未登录时进行召回推送;- 定期检查用户当前退款的账单是否被商家处理。
延迟队列的需求各位应该在日常开发的场景中经常碰到。比如:
- 用户登录之后5分钟给用户做分类推送;
- 用户多少天未登录给用户做召回推送;
- 定期检查用户当前退款账单是否被商家处理等等场景。
一般这种场景和定时任务还是有很大的区别,定时任务是你知道任务多久该跑一次或者什么时候只跑一次,这个时间是确定的。延迟队列是当某个事件发生的时候需要延迟多久触发配套事件,引子事件发生的时间不是固定的。
业界目前也有很多实现方案,单机版的方案就不说了,现在也没有哪个公司还是单机版的服务,今天我们一一探讨各种方案的大致实现。
1. Redis zset
这个方案比较常用,简单有效。利用 Redis 的 sorted set 结构,使用 timeStamp 作为 score,比如你的任务是要延迟5分钟,那么就在当前时间上加5分钟作为 score ,轮询任务每秒只轮询 score 大于当前时间的 key即可,如果任务支持有误差,那么当没有扫描到有效数据的时候可以休眠对应时间再继续轮询。
方案优劣:
优点:
简单实用,一针见血。
缺点:
- 单个 zset 肯定支持不了太大的数据量,如果你有几百万的延迟任务需求,大哥我还是劝你换一个方案;
- 定时器轮询方案可能会有异常终止的情况需要自己处理,同时消息处理失败的回滚方案,您也要自己处理。
本文共计2554个文字,预计阅读时间需要11分钟。
延迟队列的需求各位置应日常开发场景中经常遇到。例如:- 用户登录后5分钟内进行分类推送;- 用户多天未登录时进行召回推送;- 定期检查用户当前退款的账单是否被商家处理。
延迟队列的需求各位应该在日常开发的场景中经常碰到。比如:
- 用户登录之后5分钟给用户做分类推送;
- 用户多少天未登录给用户做召回推送;
- 定期检查用户当前退款账单是否被商家处理等等场景。
一般这种场景和定时任务还是有很大的区别,定时任务是你知道任务多久该跑一次或者什么时候只跑一次,这个时间是确定的。延迟队列是当某个事件发生的时候需要延迟多久触发配套事件,引子事件发生的时间不是固定的。
业界目前也有很多实现方案,单机版的方案就不说了,现在也没有哪个公司还是单机版的服务,今天我们一一探讨各种方案的大致实现。
1. Redis zset
这个方案比较常用,简单有效。利用 Redis 的 sorted set 结构,使用 timeStamp 作为 score,比如你的任务是要延迟5分钟,那么就在当前时间上加5分钟作为 score ,轮询任务每秒只轮询 score 大于当前时间的 key即可,如果任务支持有误差,那么当没有扫描到有效数据的时候可以休眠对应时间再继续轮询。
方案优劣:
优点:
简单实用,一针见血。
缺点:
- 单个 zset 肯定支持不了太大的数据量,如果你有几百万的延迟任务需求,大哥我还是劝你换一个方案;
- 定时器轮询方案可能会有异常终止的情况需要自己处理,同时消息处理失败的回滚方案,您也要自己处理。

