那些年我们追过的定时调度

3次阅读

共计 1964 个字符,预计需要花费 5 分钟才能阅读完成。

定时调度
作为后端开发人员,我们总会遇到这样的业务场景:每周同步一批数据;每半个小时检查一遍服务器运行状况;每天早上八点给用户发送一份包含今日待办事项的邮件,等等。

这些场景中都离不开“定时器”,就像一个定好时间规则的闹钟,它会在指定时间触发,执行我们想要定义的调度任务。那么我们今天就来数一下,那些年我们用过的“定时调度”。

1.job (oracle)
从刚工作就一直使用 oracle 数据库,最早接触的定时任务就是 oracle 数据库的 job。job 有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务。而且 oracle 重新启动后,job 会继续运行,不用重新启动。
而且 job 的机制非常完备,可以查询相关的表或视图,查询 job 的定时规则和执行情况。缺点是作为 oracle 数据库层面的工具,自定义功能扩展,二次开发的难度比较大。

1.1 创建 job

1.2 删除 job

1.3 查询 job

2.crontab (linux)
crond 是 linux 下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与 windows 下的计划任务类似,当安装完成操作系统后,默认会安装此服务 工具,并且会自动启动 crond 进程,crond 进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

cron 是服务名称,crond 是后台进程,crontab 则是定制好的计划任务表。大部分 linux 系统默认都安装了 cron,可以检查一下。

crontab 基本操作命令

crontab 表达式格式

3.Timer 和 ScheduledExecutorService (java)
Timer 是 jdk 中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。

TimerTask 是一个实现了 Runnable 接口的抽象类,代表一个可以被 Timer 执行的任务。
TimerTask 类是一个抽象类,由 Timer 安排为一次执行或重复执行的任务。它有一个抽象方法 run()方法,该方法用于执行相应计时器任务要执行的操作。因此每一个具体的任务类都必须继承 TimerTask,然后重写 run()方法。另外它还有两个非抽象的方法

当然,一般使用 Timer 的比较少,因为它的缺点比较明显:

1. 单线程,当多个 timer 同时运行时,会等上一个执行完成,再执行下一个。
2.Timer 线程是不会捕获异常的,如果 TimerTask 抛出的了未检查异常则会导致 Timer 线程终止。

所以一般使用 ScheduledExecutorService 替代 Timer。ScheduledExecutorService:也是 jdk 自带的一个基于线程池设计的定时任务类。其每个调度任务都会分配到线程池中的一个线程执行,所以其任务是并发执行的,互不影响。

4.SpringTask (spring)
Timer 和 ScheduledExecutorService 都是属于 jdk 层面上实现定时调度的类,功能还不足以让我们满意,那么现在介绍一个比较完善的定时调度工具 – SpringTask,是 Spring 提供的,支持注解和配置文件形式,支持 crontab 表达式,使用简单但功能强大。我个人非常喜欢 SpringTask,仅仅是因为支持 crontab 表达式。

在 springboot 里面使用方式非常简单:

1. 启动类添加开启定时调度的注解 @EnableScheduling
2. 在需要定时执行的方法上,增加注解 @Scheduled(cron =”crontab 表达式 ”)

默认的简单的使用步骤只有以上两步,但是 SpringTask 的默认使用方式也有一些不足:

1. 默认线程池的 poolsize 为 1,可以理解为 Timer 类似的单线程模式。
无法动态修改 crontab 表达式,修改完只能重新部署后,才能生效。

问题 1 的解决方式,可以通过自定义 TaskExecutor 来修改当前的线程池。问题 2,则可以直接使用 threadPoolTaskScheduler 类实现自定义的定时调度规则。

附解决两个问题的源码 TaskTimer.class

5.Quartz (其他产品)
Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。它是一个功能强大、十分成熟的重量级产品,还支持负载均衡,实现分布式调度。

不过,对于 Quartz 的安装你要多花点功夫了,从数据库要建哪些表,到应用程序该如何部署。对于这样一个庞大的产品,本篇文章就不附上它的使用说明书了。

本人创业团队产品 MadPecker,主要做 BUG 管理、测试管理、应用分发,网址:www.madpecker.com,有需要的朋友欢迎试用、体验!
本文为 MadPecker 团队技术人员编写,转载请标明出处

正文完
 0