概括
本文将介绍quartz的基本概念,简单使用,持久化,单机、集群配置等,方便各位同学快速了解quartz框架,并合理运用到项目中。
quartz简介
quartz是一个为java服务量身定制的定时任务框架,提供了持久化方案,集群解决方案,方便我们对一些简单场景的使用;对比其他定时任务方案,可以说是@Scheduled注解的升级版,但又不及xxl-job的强大
quartz 官网:https://www.quartz-scheduler.org/
quartz的四大组件
quartz总共有4个组件,基本上所有的操作都是围绕这几个组件来完成的

JobDetail
对Job任务的简单描述,可以设置job的名称,组,简单描述信息,携带的JobData数据,是否持久化等
- name,group:组成jobKey(本服务job的唯一标识)
- Description:job任务的简单描述
- JobData:Map子类,主要用于传递数据,方便job代码中使用
- storeDurable:是否持久化,当job不再被调用时,jobDetail信息继续存储在数据库中,不被删除
- requestRecovery:是否恢复执行
Job
Job是一个接口,如果你定义一个任务类,就需要实现Job接口,并实现execute方法,job任务的业务代码放在execute方法中,被调用时可执行,方法参数中注入了JobExecutionContext对象,可以获取到jobDetail信息,JobData等内容
- execute方法:任务业务代码执行方法,类似于Runable中的run方法
- @DisallowConcurrentExecution:禁止并发执行,如果是两个job,那就是串型话
- @PersistJobDataAfterExecution:执行后更新jobData中的数据,考虑并发数据问题,最好和@DisallowConcurrentExecution一起使用
Trigger
trigger是触发器,主要是用于定于触发时间,间隔,方案等
- name和troup:trigger的唯一标识,同jobDetail
- Description:trigger的简单描述
- startAt:trigger工作开始时间,通过配置此项可设置在某个时间点后执行
- endAt:trigger工作结束时间,通过配置此项可设置在某个时间点前执行
- withSchedule:设置触发器频率实现方式,有四个实现方式

一般常用的是CronScheduleBuilder 和 SimpleScheduleBuilder两个
CronScheduleBuilder:通过设置cron表达式的方式来控制触发频率(如一秒执行一次 0/1 * * * * ?等)
SimpleScheduleBuilde:简单通过代码方式设置隔多久触发一次,例如每隔5秒
Schedule
这个和trigger中的ScheduleBuilder不同,这个Schedule是整个Quartz的调度器,用于控制任务的调度,在Schedule可以设置持久化,集群配置等
注意:Schedule在scheduleJob方法将JobDetail与Trigger关联之前,JobDetail和Trigger没有半毛钱关系。同时,因为JobDetail和Trigger等都有name和group,可以通过排列组合来完成不同的搭配,不过这种方案有点繁琐了,在需求不是很离谱的情况下,通常都是一个job配一个专门的trigger,舍弃那些排列组合,方便明了
SpringBoot整合Quartz
单机版
依赖
springboot选择2.2.1.RELEASE版本,其它跟随springboot的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
编写一个job类用于执行业务代码
// 实际job执行类
@Log4j2
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//执行业务逻辑
log.info("执行业务...");
}
}
编写JobDetail和Trigger,并调用
@Component
public class QuartzService implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
// 项目初始化完成后执行,quartz业务
// 调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// job详情,描述job的执行类,job的名称,组等
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("jobName1", "group1")
.build();
// 触发器,描述触发器的名称、组,执行间隔等(有cron方式,也有简单的隔多久执行一次)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("triggerName1", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(10))
.build();
// 在调度器上关联job和触发器
scheduler.scheduleJob(jobDetail,trigger);
// 启动调度器
scheduler.start();
}
}
很好,现在就完成了一个Quartz单机版和SpringBoot的整合项目,来看看执行效果,都是每10秒执行一次

以上只是简单单机版的做法,相比@Schedule也没强多少,却少持久化,集群重复执行问题
集群版
集群版解决了同一时间重复的问题,同时,集群依赖持久化,用的是mysql的锁来解决集群间调度的问题
对比单机版,需要额外添加mysql相关的依赖,并在对应的mysql库中创建quartz持久化相关的表
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
-- ----------------------------
-- 1、存储每一个已配置的 jobDetail 的详细信息
-- ----------------------------
create table QRTZ_JOB_DETAILS (
sched_name varchar(120) not null comment '调度名称',
job_name varchar(200) not null comment '任务名称',
job_group varchar(200) not null comment '任务组名',
description varchar(250) null comment '相关介绍',
job_class_name varchar(250) not null comment '执行任务类名称',
is_durable varchar(1) not null comment '是否持久化',
is_nonconcurrent varchar(1) not null comment '是否并发',
is_update_data varchar(1) not null comment '是否更新数据',
requests_recovery varchar(1) not null comment '是否接受恢复执行',
job_data blob null comment '存放持久化job对象',
primary key (sched_name, job_name, job_group)
) engine=innodb comment = '任务详细信息表';
-- ----------------------------
-- 2、 存储已配置的 Trigger 的信息
-- ----------------------------
create table QRTZ_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
trigger_name varchar(200) not null comment '触发器的名字',
trigger_group varchar(200) not null comment '触发器所属组的名字',
job_name varchar(200) not null comment 'qrtz_job_details表job_name的外键',
job_group varchar(200) not null comment 'qrtz_job_details表job_group的外键',
description varchar(250) null comment '相关介绍',
next_fire_time bigint(13) null comment '上一次触发时间(毫秒)',
prev_fire_time bigint(13) null comment '下一次触发时间(默认为-1表示不触发)',
priority integer null comment '优先级',
trigger_state varchar(16) not null comment '触发器状态',
trigger_type varchar(8) not null comment '触发器的类型',
start_time bigint(13) not null comment '开始时间',
end_time bigint(13) null comment '结束时间',
calendar_name varchar(200) null comment '日程表名称',
misfire_instr smallint(2) null comment '补偿执行的策略',
job_data blob null comment '存放持久化job对象',
primary key (sched_name, trigger_name, trigger_group),
foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group)
) engine=innodb comment = '触发器详细信息表';
-- ----------------------------
-- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数
-- ----------------------------
create table QRTZ_SIMPLE_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
repeat_count bigint(7) not null comment '重复的次数统计',
repeat_interval bigint(12) not null comment '重复的间隔时间',
times_triggered bigint(10) not null comment '已经触发的次数',
primary key (sched_name, trigger_name, trigger_group),
foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
) engine=innodb comment = '简单触发器的信息表';
-- ----------------------------
-- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息
-- ----------------------------
create table QRTZ_CRON_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
cron_expression varchar(200) not null comment 'cron表达式',
time_zone_id varchar(80) comment '时区',
primary key (sched_name, trigger_name, trigger_group),
foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
) engine=innodb comment = 'Cron类型的触发器表';
-- ----------------------------
-- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)
-- ----------------------------
create table QRTZ_BLOB_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
blob_data blob null comment '存放持久化Trigger对象',
primary key (sched_name, trigger_name, trigger_group),
foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
) engine=innodb comment = 'Blob类型的触发器表';
-- ----------------------------
-- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围
-- ----------------------------
create table QRTZ_CALENDARS (
sched_name varchar(120) not null comment '调度名称',
calendar_name varchar(200) not null comment '日历名称',
calendar blob not null comment '存放持久化calendar对象',
primary key (sched_name, calendar_name)
) engine=innodb comment = '日历信息表';
-- ----------------------------
-- 7、 存储已暂停的 Trigger 组的信息
-- ----------------------------
create table QRTZ_PAUSED_TRIGGER_GRPS (
sched_name varchar(120) not null comment '调度名称',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
primary key (sched_name, trigger_group)
) engine=innodb comment = '暂停的触发器表';
-- ----------------------------
-- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息
-- ----------------------------
create table QRTZ_FIRED_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
entry_id varchar(95) not null comment '调度器实例id',
trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
instance_name varchar(200) not null comment '调度器实例名',
fired_time bigint(13) not null comment '触发的时间',
sched_time bigint(13) not null comment '定时器制定的时间',
priority integer not null comment '优先级',
state varchar(16) not null comment '状态',
job_name varchar(200) null comment '任务名称',
job_group varchar(200) null comment '任务组名',
is_nonconcurrent varchar(1) null comment '是否并发',
requests_recovery varchar(1) null comment '是否接受恢复执行',
primary key (sched_name, entry_id)
) engine=innodb comment = '已触发的触发器表';
-- ----------------------------
-- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例
-- ----------------------------
create table QRTZ_SCHEDULER_STATE (
sched_name varchar(120) not null comment '调度名称',
instance_name varchar(200) not null comment '实例名称',
last_checkin_time bigint(13) not null comment '上次检查时间',
checkin_interval bigint(13) not null comment '检查间隔时间',
primary key (sched_name, instance_name)
) engine=innodb comment = '调度器状态表';
-- ----------------------------
-- 10、 存储程序的悲观锁的信息(假如使用了悲观锁)
-- ----------------------------
create table QRTZ_LOCKS (
sched_name varchar(120) not null comment '调度名称',
lock_name varchar(40) not null comment '悲观锁名称',
primary key (sched_name, lock_name)
) engine=innodb comment = '存储的悲观锁信息表';
-- ----------------------------
-- 11、 Quartz集群实现同步机制的行锁表
-- ----------------------------
create table QRTZ_SIMPROP_TRIGGERS (
sched_name varchar(120) not null comment '调度名称',
trigger_name varchar(200) not null comment 'qrtz_triggers表trigger_name的外键',
trigger_group varchar(200) not null comment 'qrtz_triggers表trigger_group的外键',
str_prop_1 varchar(512) null comment 'String类型的trigger的第一个参数',
str_prop_2 varchar(512) null comment 'String类型的trigger的第二个参数',
str_prop_3 varchar(512) null comment 'String类型的trigger的第三个参数',
int_prop_1 int null comment 'int类型的trigger的第一个参数',
int_prop_2 int null comment 'int类型的trigger的第二个参数',
long_prop_1 bigint null comment 'long类型的trigger的第一个参数',
long_prop_2 bigint null comment 'long类型的trigger的第二个参数',
dec_prop_1 numeric(13,4) null comment 'decimal类型的trigger的第一个参数',
dec_prop_2 numeric(13,4) null comment 'decimal类型的trigger的第二个参数',
bool_prop_1 varchar(1) null comment 'Boolean类型的trigger的第一个参数',
bool_prop_2 varchar(1) null comment 'Boolean类型的trigger的第二个参数',
primary key (sched_name, trigger_name, trigger_group),
foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
) engine=innodb comment = '同步机制的行锁表';
commit;
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- JSON工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 实现对数据库连接池的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
mysql连接配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: quartz
password: quartz
driver-class-name: com.mysql.cj.jdbc.Driver
Quartz的Schedule配置,可以用properties的配置文件方式,我这直接写代码中了
主要注意
factory.setDataSource(dataSource);配置持久化数据源
prop.put("org.quartz.jobStore.isClustered", "true");配置集群模式
factory.setSchedulerName("cluster");设置服务名称,多服务时靠这个区分是哪个服务的标识
@Configuration
public class QuartzConfig {
@Autowired
private DataSource dataSource;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws SchedulerException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
// quartz参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "cluster");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
// 线程池配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
// JobStore配置
prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
// 集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10");
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
// sqlserver 启用
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
factory.setQuartzProperties(prop);
factory.setSchedulerName("cluster");
// 延时启动
factory.setStartupDelay(1);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
// 可选,QuartzScheduler
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
// 设置自动启动,默认为true
factory.setAutoStartup(true);
return factory;
}
}
job业务类
@Log4j2
@PersistJobDataAfterExecution // 执行后更新jobData中的数据,考虑并发数据问题,最好和@DisallowConcurrentExecution一起使用
@DisallowConcurrentExecution // 不允许并发执行
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 业务逻辑
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
String description = jobExecutionContext.getJobDetail().getDescription();
log.info("hello ... data {}, description {}", JSON.toJSONString(jobDataMap),description);
}
}
JobDetail和Trigger
注意,因为持久化的原因,项目在启动的时候会自动将数据库中的job初始化加载到服务中,如果代码中还是直接将创建job相关的代码写死的话,就会报JobKey已存在等问题,这时候就需要判断是否存在来创建job,单机本不用考虑此问题
@Log4j2
@Component
public class QuartzInitService implements CommandLineRunner {
@Autowired
private Scheduler scheduler;
@Override
public void run(String... args) throws Exception {
// 完成初始化的job工作
// 判断job是否存在,如果存在就不创建
// 因为是采用数据库存储,在重启时不能重复创建job
JobKey jobKey = JobKey.jobKey("job1", "group1");
if(!scheduler.checkExists(jobKey)){
// job
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("job1", "group1")
.withDescription("测试job")
.usingJobData("1",2)
.requestRecovery() // 设置是否恢复执行
.build();
// trigger
SimpleTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(
SimpleScheduleBuilder
// .simpleSchedule() // 如果只是这个,只会执行一次
.repeatSecondlyForever(5)
)
.build();
scheduler.scheduleJob(jobDetail,trigger);
}
}
}
这样就完成了Quartz集群化的搭建
quartz任务常见操作
cron表达式的任务
@Test
void addCronJob() throws SchedulerException {
// cron 表达式job
// 舍弃排列组合,以jobName的名称当成job、trigger的名称
String jobName = "cronJob";
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withDescription(jobName)
.withIdentity(jobName,jobName)
.usingJobData("name",jobName)
.build();
// jobDetail.isDurable()
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName,jobName)
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) // 每两秒执行一次
.build();
scheduler.scheduleJob(jobDetail,trigger);
}
延时执行一次的任务
@Test
void addDelayJob() throws SchedulerException, ParseException {
// 舍弃排列组合,以jobname的名称当成job、trigger的名称
String jobName = "delayJob";
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity(jobName, jobName)
.withDescription("延时job")
.build();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 延时触发器实现方式
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobName)
.startAt(DateBuilder.futureDate(20, DateBuilder.IntervalUnit.SECOND)) // 触发器开始工作时间,在此之前,都不会进行操作
.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.build();
// 可以通过设置startAt和endAt,配合.withSchedule等,设置定时任务在某个时间范围内才能执行
scheduler.scheduleJob(jobDetail,trigger);
// 延时任务完成后会自动删除,就算job设置持久化也会删除trigger
log.info("delayJob commit ");
}
执行固定次数的任务
@Test
void addRepeatCount() throws SchedulerException {
// 创建一个指定次数的任务
int count = 10;
// 舍弃排列组合,以jobname的名称当成job、trigger的名称
String jobName = "repeatCountJob";
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity(jobName, jobName)
.withDescription("延时job")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobName)
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2) // 每2s执行一次
.withRepeatCount(count) // 任务重复触发次数,设置10次,实际执行11次
)
.build();
scheduler.scheduleJob(jobDetail,trigger);
}
指定时间范围的任务
@Test
void addTimeScopeJob() throws SchedulerException {
// 添加在一定时间范围的job
// 舍弃排列组合,以jobname的名称当成job、trigger的名称
String jobName = "timeScopeJob";
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity(jobName, jobName)
.withDescription(jobName)
.storeDurably()
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, jobName)
.withSchedule(
CronScheduleBuilder.cronSchedule("0/1 * * * * ?")
)
// 设置触发器运行的时间返回,以下内容为,接下来的第20-25秒这几秒秒时间范围内,会触发执行
// 传入时间类型为Date,也可以通过其他格式设置时间范围,例如yyyy-MM-dd HH:mm:ss等
.startAt(DateBuilder.futureDate(20, DateBuilder.IntervalUnit.SECOND))
.endAt(DateBuilder.futureDate(25, DateBuilder.IntervalUnit.SECOND))
.build();
scheduler.scheduleJob(jobDetail,trigger);
// 任务完成后会自动删除
}
暂停任务
@Test
void pauseJobDetail() throws SchedulerException {
// 暂停任务
String jobName = "job1";
String jobGroup = "group1";
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
scheduler.pauseJob(jobKey);
}
恢复任务
@Test
void resumeJobDetail() throws SchedulerException {
// 恢复任务
String jobName = "cronJob";
JobKey jobKey = JobKey.jobKey(jobName, jobName);
scheduler.resumeJob(jobKey);
}
删除任务
@Test
void deleteJob() throws SchedulerException {
// 删除任务
String jobName = "cronJob";
JobKey jobKey = JobKey.jobKey(jobName, jobName);
scheduler.deleteJob(jobKey);
}
清除全部任务
@Test
void clearJob() throws SchedulerException {
// 清除全部任务
scheduler.clear();
}
立即执行一次任务
@Test
void exeJobTest(){
// 立即执行一次
String name = "001";
JobKey jobKey = JobKey.jobKey(name, name);
scheduler.triggerJob(jobKey);
}
总结
这几乎就是quartz定时任务常用的操作了,job的持久化,集群调度,控制并发执行,提供多种触发器,延时任务,时间范围控制等,对比简单的需求基本上就是足够了
总的来说,quartz入门简单,通过嵌入服务代码中,避免多使用其它机器来搭建job集群,适合少量服务的集群环境下使用
但是对比xxl-job,功能少(比如日志,调度方案,可视化界面等)不过xxl-job要自身搭建集群,需要额外的服务器资源
如果是服务众多,又需要面对各种复杂的环境,那么还是推荐使用XXL-JOB
2662

被折叠的 条评论
为什么被折叠?



