之前工作中用到过Spring Task,相对于现公司的分布式项目,Quartz更加契合项目,趁着空闲时间自己配置一下。
Task和Quartz的比较:
网上这方面资料很多,我就简述总结一下:
- Task注解方式十分简单,Quartz需要手动配置Jobs。
- Task默认单线程串行执行任务,若前一个任务超时,会影响下一个任务,若需并发执行,需手动设置线程池。Quartz采用多线程,无这个问题。
- Quartz可采用集群方式,分布式部署到多台机器上,分配定时任务。
配置:
maven添加:
以下只给出quartz包,其他例如mysql,请自行添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
application.yml配置:
网上很多配置都是基于quartz.properties配置,在springboot2.0里集成最新的quartz版本是可以采用yml配置的。
本文采用数据方式存储任务配置。若采用内存方式,注释jobStore和job-store-type配置内容即可。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.114.128:3306/febs_quartz?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: star
password: 123456
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: MyScheduler
instanceId: AUTO
#quartz默认采用内存方式储存定时任务,这里启用jobStore设置为数据库方式。
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式,默认MEMORY内存
job-store-type: jdbc
#初始化表结构
#jdbc:
#initialize-schema: never
配置管理工具类:
该工具类,方便管理任务。用于添加,修改,删除,暂停,启动任务。
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author FCX
* @date Create in 10:29 2019/9/25
* @description TODO
*/
@Component
public class QuartzManager {
/**
* 注入任务调度器
*/
@Autowired
private Scheduler sched;
private static String JOB_GROUP_NAME = "ATAO_JOBGROUP"; //任务组
private static String TRIGGER_GROUP_NAME = "ATAO_TRIGGERGROUP"; //触发器组
/**
* 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
*
* @param jobName 任务名
* @param cls 任务
* @param time 时间设置,参考quartz说明文档
*/
public void addJob(String jobName, Class<? extends Job> cls, String time) {
try {
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
CronTrigger trigger = TriggerBuilder
.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 启动
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 (带参数)
*
* @param jobName 任务名
* @param cls 任务
* @param time 时间设置,参考quartz说明文档
*/
public void addJob(String jobName, Class<? extends Job> cls, String time, Map<String, Object> parameter) {
try {
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
jobDetail.getJobDataMap().put("parameterList", parameter); //传参数
CronTrigger trigger = TriggerBuilder
.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); //