目录
https://www.quartz-scheduler.org/
官方描述:
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
翻译:
Quartz 是一个有丰富特性,开源任务调度库,能和任意(从单个小应用到大型系统.) Java 应用集成.Quartz 用于创建简单或者混合 调度器用于执行数以千计的任务.Quartz Scheduler 包含了很多企业级特性,例如支持 JTA.
下载地址 :https://www.quartz-scheduler.org/downloads/
或者 引入pom 依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- 日志简单实现 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
<scope>compile</scope>
</dependency>
需下载 slf4j-simple.jar 包,否则使用SLF4j打印日志会报错:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
在 classpath 添加 quartz.properties 文件,添加配置信息:
# 调度器名字
org.quartz.scheduler.instanceName = black-scheduler
# 线程池大小
org.quartz.threadPool.threadCount = 3
# 任务存储方式(RAMJobStore : 内存存储)
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
更详细配置参见 https://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration
package org.black.demo.quartz;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloJob implements Job{
private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount());
LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
测试结果:
[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created.
[main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'black-schedule' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'black-schedule' initialized from default resource file in Quartz package: 'quartz.properties'
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0
[main] INFO org.quartz.core.QuartzScheduler - Scheduler black-schedule_$_NON_CLUSTERED started.
[main] INFO org.black.demo.quartz.QuartzScheduleDemo - Quartz 调度器启动时间:Tue Dec 28 11:51:03 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463495
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:07
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:07 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@4dab129f
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:03,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463496
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:51:03
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:11
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:11 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@5a318665
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:07,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCronTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCronTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
// cron 表达式: 秒 分 时 日 月 周 年
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ? *"))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
withSchedule 方法可以设置不同的触发器类型.CronScheduleBuilder 继承自 ScheduleBuilder,ScheduleBuilder 的子类一共有4个,也就是可以设置 4中类型的触发器.
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.CalendarIntervalScheduleBuilder;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz Calendar 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCalendarTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCalendarTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInSeconds(10))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.DailyTimeIntervalScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TimeOfDay;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz daily time 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDailyTimeTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDailyTimeTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务,到 11点27分停止触发
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withIntervalInSeconds(10)
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(11, 27)))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}", date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
上边的示例都是存储在内存中,这里展示了如何存储在数据库中.
数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下.我这里使用的是mysql 数据库,选择tables_mysql_innodb.sql 脚本执行.脚本内容如下:
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;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(190) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
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;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
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;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
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;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
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;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (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;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(190) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(190) NULL,
JOB_GROUP VARCHAR(190) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
commit;
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
## Quartz 配置信息
# 调度器名字
org.quartz.scheduler.instanceName = black-schedule
# 线程池大小
org.quartz.threadPool.threadCount = 3
# ====================================================================================== #
# 任务存储方式选择 JDBC存储(对应sql在 org.quartz.impl.jdbcjobstore.Constants 常量类中)
# JDBC 存储有两个实现 JobStoreCMT 和 JobStoreXT ,其中:
# JobStoreCMT:使用JTA容器管理事务,自己并不处理事务提交和回滚
# JobStoreTX: 通过 JDBC 自己管理事务提交和回滚,适合单体应用.
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据库驱动委派类(必须配置)
# org.quartz.impl.jdbcjobstore.StdJDBCDelegate (for fully JDBC-compliant drivers)
# org.quartz.impl.jdbcjobstore.MSSQLDelegate (for Microsoft SQL Server, and Sybase)
# org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
# org.quartz.impl.jdbcjobstore.WebLogicDelegate (for WebLogic drivers)
# org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
# org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.CloudscapeDelegate
# org.quartz.impl.jdbcjobstore.DB2v6Delegate
# org.quartz.impl.jdbcjobstore.DB2v7Delegate
# org.quartz.impl.jdbcjobstore.DB2v8Delegate
# org.quartz.impl.jdbcjobstore.HSQLDBDelegate
# org.quartz.impl.jdbcjobstore.PointbaseDelegate
# org.quartz.impl.jdbcjobstore.SybaseDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 数据源配置(必须配置) blackQuartz 是数据源名字
org.quartz.jobStore.dataSource = blackQuartz
# Quartz 表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
# 指示 JobDataMaps 中的所有数据都是 String 类型,这样不用序列化存储到 BLOB 列中
org.quartz.jobStore.useProperties=false
# 多长时间认定 触发器错过了下次触发时间,默认 60000 毫秒
org.quartz.jobStore.misfireThreshold=60000
# 开启集群特性
org.quartz.jobStore.isClustered=false
# 集群检查频率间隔,默认15000毫秒
org.quartz.jobStore.clusterCheckinInterval=15000
# 一次性处理未触发的触发器最大数量,默认 20
org.quartz.jobStore.maxMisfiresToHandleAtATime=20
# 不允许 setAutoCommit(false) true-不允许,false-允许
org.quartz.jobStore.dontSetAutoCommitFalse=false
# 加锁查询 LOCKS 表的一行数据,{0}是表前缀(tablePrefix),{1}是调度器名字
org.quartz.jobStore.selectWithLockSQL="SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE"
# 设置事务隔离级别为串行 true-设置,false-不设置
org.quartz.jobStore.txIsolationLevelSerializable=false
# 如果 org.quartz.scheduler.batchTriggerAcquisitionMaxCount >1 那么此属性必须设置为 true
org.quartz.jobStore.acquireTriggersWithinLock=false
# 锁处理类,用于生产 Semaphore 实例在 job store data 上进行锁控制
#org.quartz.jobStore.lockHandler.class=null
# 管道分隔的属性集合 在初始化阶段传给DriverDelegate使用,格式:"settingName=settingValue|otherSettingName=otherSettingValue|..."
#org.quartz.jobStore.driverDelegateInitString=
# ====================================================================================== #
# ====================================================================================== #
# 数据源名字为blackQuartz的 数据源配置(数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下)
# ====================================================================================== #
org.quartz.dataSource.blackQuartz.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.blackQuartz.URL = jdbc:mysql://localhost:3306/black?characterEncoding=UTF8&connectTimeout=6000&socketTimeout=6000&connectionTimeZone=Asia/Shanghai
org.quartz.dataSource.blackQuartz.user = black
org.quartz.dataSource.blackQuartz.password = Black@123
org.quartz.dataSource.blackQuartz.maxConnections = 5
org.quartz.dataSource.blackQuartz.validationQuery=select 0
package org.black.demo.quartz;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloJob implements Job{
private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount());
LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleJDBCDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleJDBCDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
StdSchedulerFactory factory = new StdSchedulerFactory();
// 指定加载quartz-jdbc.properties配置
factory.initialize("quartz-jdbc.properties");
Scheduler scheduler = factory.getScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
控制台输出:
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:05,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163286
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:05
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:13 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@f8b8a7d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:09,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163287
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:09
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:17
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:17 CST 2021
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@7a800c47
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:13,当前线程:black-schedule_Worker-3 - 执行 HelloJob 任务
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163288
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:21
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:21 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@1053e9f7
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:17,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
执行以下sql查询 表数据:
select * from QRTZ_JOB_DETAILS;
select * from QRTZ_FIRED_TRIGGERS;
select * from QRTZ_PAUSED_TRIGGER_GRPS;
select * from QRTZ_SCHEDULER_STATE;
select * from QRTZ_LOCKS;
select * from QRTZ_SIMPLE_TRIGGERS;
select * from QRTZ_SIMPROP_TRIGGERS;
select * from QRTZ_CRON_TRIGGERS;
select * from QRTZ_BLOB_TRIGGERS;
select * from QRTZ_TRIGGERS;
select * from QRTZ_JOB_DETAILS;
select * from QRTZ_CALENDARS;
待续…
手机扫一扫
移动阅读更方便
你可能感兴趣的文章