作者|伊星宇
动态定时任务,就是在不重启服务的状态下,可以做到继续添加,更新已有,删除已有任务。定时任务有很多实现的方式,包括timer,timertask,scheduledexecutorservice,以及第三方框架Quartz。本篇文章主要介绍SpringBoot整合Quartz实现动态定时任务。
什么是Quartz以及Quartz的基本组成
1、Quartz是功能强大的开源作业调度库,可以创建简单或复杂的计划,可以运行十个,百个,甚至几万个Jobs这样复杂的日程序表。
2、quartz的基本组成如下:

Quarqz的应用
Quartz的典型使用场景,主要就是用来执行定时任务,例如:定时发送信息,定时生成报表,自动更新静态数据等等。接下来结合接口测试平台,首先看看需求中定时任务要实现的功能,如下图:


其中主要功能包括创建,编辑,删除,暂停,恢复等基本功能,对于创建定时任务的规则,按照每天指定时间,或者间隔多少小时循环执行定时任务,循环次数是可进行限制的。最重要的当用户操作时,在作业调度scheduler中,动态添加,更新,删除任务等,不需要重启服务即可实现。
整合开始
1、在工程pom文件中,添加依赖

2、添加配置
因为springBoot已经集成了quartz,所以直接配置application.yaml文件即可;这里使用了quartz的默认配置,所以没有在yaml文件中自定义定时任务的配置,这里说下quartz的两种基本作业存储类型RAMJobStore和JDBC作业存储,两种类型的优缺点如下:
RAMJobStore
JDBC作业存储
因为本篇采用默认配置,所以存储类型是RAMJobStore。同样,可以根据项目特点进行切换,需要在application.yaml配置中增加如下配置信息,以及按照官方文档提供sql创建数据表。本篇不过多介绍这种方式。

3、添加quartz配置
spring通过SchedulerFactoryBean来管理Quartz的生命周期。在spring启动容器时启动调度器,在spring关闭容器时关闭调度器。

4、创建任务,实现Job,其只有一个方法execute方法,主要编写定时任务的处理逻辑。

5、定义定时任务的操作
包括服务启动时开始执行全部任务timingTask,新增addJob,更新updateJob,操作operateJob(删除,暂停,恢复)。

服务层对接口进行实现,将触发器Trigger设定的触发规则,以及任务描述JobDetail,交给作业调度Scheduler进行管理。

这里的触发器采用的是SimpleTrigger。

6、定义接口
将用户提交的信息保存到数据库中,同时调用创建定时任务的接口,将它交给调度作业Scheduler进行管理,这样实现了动态的定时任务,不需要进行停机再启动就可以添加,编辑等,对正在运行任务进行操作。

7、定时任务表设计如下图:

8、执行效果如下图:

9、服务启动时,将所有表中已存在任务添加到调度作业进行管理。
注:SpringBoot在项目启动后会遍历所有实现CommandLineRunner的实体类并执行run方法。

总结
到这里本篇介绍的内容就结束了,Quartz功能的确很强大,与SpringBoot的框架整合也很方便,可以满足很多复杂的调度需求,对于初次接触Quartz的我来说,上手还是相对比较简单方便,在这里给大家提个醒,所有的技术,不是越高端越好,而是要根据需求选择适合的技术去实现。
友情提醒:
1、如果采用内存作业存储类型,重启后执行次数会被清零,所以有这方面需求的小伙伴,记得采用数据库作业存储类型;
2、针对于Quartz集群部署情况,建议采用数据库作业存储类型,因为集群中每个节点是一个独立的Quartz应用,该集群需要分别对每个节点进行启动和停止操作,不像普通的服务集群。Quartz应用是通过数据库表来感知另一个应用,只有持久化的JobStore才能完成Quartz集群。如果采用内存作业存储类型,分布式部署需要增加锁机制,例如:redis锁等,防止重复多次执行。