方案一:基于SpringTask定时扫描数据库
步骤: 把发布的任务和时间保存到数据库中之后使用定时任务SpringTask来进行每五分钟执行一次
优点:可以把任务持久化保存到数据库中,不容易丢失任务
缺点:这种方案发布的时间可能会有误差,因为五分钟才执行一次,如果缩短时间设置一分钟或者几十秒执行一次那么数据库压力非常大,所以这种方案不太理想
方案二 :基于jdk自带DelayQueue
步骤:DelayQueue 延时获取元素阻塞队列,队列根据任务的时间进行排序,使用while true循环不断的尝试从队列中取出任务
优点:这种方案执行速度非常快,因为所有的数据都存在JVM中
而且他的消费任务的时间非常准确
缺点:没有持久化保存当java程序出错了很有可以造成任务数据的丢失,所以这种方案也不太符合
方案三:基于rabbitMQ的死信队列
步骤:把消息放到一个队列中(这个队列没有消费者,给消息设置了超时时间TTL),当到了超时时间后变成死信,MQ把死信交给绑定好的死信交换机,由死信交换机在交给目标队列,监听者监听这个目标队列即可
优点:使用简单,mq帮我们管理了整个过程
可以持久化保存,不容易丢失任务
缺点:项目里必须要有rabbitMQ(我们项目中没有MQ所以这个方案也不太符合)
方案四:基于redis的Zset (redis中的Zset是有序不可重复的)
步骤:把延迟任务和时间储存到Zset中,定时扫描Zset取出任务进行消费
优点:这种方案性能好,有一定的持久化的能力,
缺点:这种方案项目里必须有redis
持久化能力不太强,
最终方案:我采用的是rebis和Mysql相结合的方式 MYsql保证了持久化保存
最终方案的总体流程
现将延时任务保存到数据库中,redis中的Zset定时获取数据库中五分钟内要执行的任务,文章来源:https://www.toymoban.com/news/detail-644294.html
redis中的list(Redis中的list是双向链表,增删效率高)定时获取Zset中需要立即执行的任务,最后从list中获取任务进行消费文章来源地址https://www.toymoban.com/news/detail-644294.html
到了这里,关于实现延迟队列的几种方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!