首页
学习
活动
专区
工具
TVP
发布

延时任务方案汇总

引言

首先,给大家道个歉,本周比较忙,所以本周才更了一篇。另外写这篇的原因就是,在填

《分布式事务之TCC模型》

这篇的坑的时候,发现引用的知识比较多,因此必须先写这篇。

另外,我在博客园写过《分布式之延时任务方案解析》,地址为:

由于博客园文章的布局不适合直接用在微信公众号上,因此我对博客园那篇进行整理,省去了代码实现,只留下思路。如果大家要查询具体的实现代码,可以另外再去百度。

OK,开始正文

正文

首先呢,要先明白定时任务延时任务的区别,主要是如下三点

(1)定时任务有明确的触发时间,延时任务没有

(2)定时任务有执行周期,而延时任务在某事件触发后一段时间内执行,没有执行周期

(3)定时任务一般执行的是批处理操作是多个任务,而延时任务一般是单个任务

数据库轮询

此方案很easy,即将延时任务存进数据库的表中,然后通过一个线程定时的去扫描数据库,不断的将任务的触发时间和当前时间进行比较,如果达到任务的触发时间,就执行任务!

优点:简单易行,支持集群操作

缺点:(1)对服务器内存资源、cpu资源消耗大

(2)存在延迟,比如你每隔3分钟扫描一次,那最坏的延迟时间就是3分钟

(3)在互联网项目中,经常会遇到有几千万条延时任务在跑。那么,数据库里延时任务表里就有几千万条记录,每隔几分钟这样扫描一次,数据库损耗极大

JDK的延迟队列

该方案是利用自带的来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入中的对象,是必须实现接口的。

实现工作流程如下图所示

其中():获取并移除队列的超时元素,没有则返回空

():获取并移除队列的超时元素,如果没有则当前线程,直到有元素满足超时条件,返回结果。

优点::效率高,任务触发时间延迟低

缺点::(1)服务器重启后,数据全部消失,怕宕机

   (2)集群扩展相当麻烦

   (3)因为内存条件限制的原因,比如在互联网项目中,延时任务通常十分的多,如果全丢JVM,内存容易OOM

   (4)代码复杂度较高

时间轮算法

先上一张时间轮的图(这图到处都是啦)

时间轮算法可以类比于时钟,如上图箭头(指针)按某一个方向按固定频率轮动,每一次跳动称为一个。这样可以看出定时轮由个3个重要的属性参数,(一轮的tick数),(一个的持续时间)以及 (时间单位),例如当=60,=1,=秒,这就和现实中的始终的秒针走动完全类似了。

如果当前指针指在1上面,我有一个任务需要4秒以后执行,那么这个执行的线程回调或者消息将会被放在5上。那如果需要在20秒之后执行怎么办,由于这个环形结构槽数只到8,如果要20秒,指针需要多转2圈。位置是在2圈之后的5上面(20 % 8 + 1)

优点::效率高,任务触发时间延迟时间比delayQueue低,代码复杂度比delayQueue低。

缺点::(1)服务器重启后,数据全部消失,怕宕机

   (2)集群扩展相当麻烦

   (3)这种情况也是把任务丢JVM内存,因为内存条件限制的原因,,那么很容易就出现OOM异常

redis相关特性

利用redis的zset数据结构

是一个有序集合,每一个元素(member)都关联了一个,通过排序来取集合中的值。

具体如下图所示,我们将超时时间戳与延时任务分别设置为和,系统扫描第一个元素判断是否超时,具体如下图所示

取出最小的元素,与当前时间进行比较,如果发现已经到达时间,则执行任务。

键空间机制

该方案使用的,中文翻译就是键空间机制,就是利用该机制可以在失效之后,提供一个回调,实际上是会给客户端发送一个消息。是需要版本2.8以上。

做法很简单:

(1)给设置一个超时时间

(2)给超时事件订阅一个处理方法

(3超时了,将回调步骤(2)中订阅的方法

ps:官网不推荐使用该机制。因为Redis的发布/订阅目前是即发即弃(fire and forget)模式的,因此无法实现事件的可靠通知。也就是说,如果发布/订阅的客户端断链之后,此时刚好key的失效期到了,如果此时客户端又无法连接到,那么该延时任务就将丢失。即使客户端又恢复了连接,也不会再次回调。

优点:(1)由于使用Redis作为消息通道,消息都存储在Redis中。如果发送程序或者任务处理程序挂了,重启之后,还有重新处理数据的可能性。

   (2)做集群扩展相当方便

   (3)时间准确度高

缺点:(1)需要额外进行redis维护

使用消息队列

利用消息队列的某些特性实现延时队列,例如我们可以实现rabbitMQ的延时队列。具体配置就不说了,大家可以自行查询。

优点: 高效,可以利用rabbitmq的分布式特性轻易的进行横向扩展,消息支持持久化增加了可靠性。

缺点:本身的易用度要依赖于rabbitMq的运维.因为要引用rabbitMq,所以复杂度和成本变高

总结

本文总结了互联网中常见的延时任务方案,希望大家有所收获!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181223G09RSE00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券