Quartz 2.2.1版本单独使用实战
Maven依赖包
在Maven工程中添加Quartz2.2.1版本的依赖,如下
<properties>
<quartz.version>2.2.1</quartz.version>
</properties>
<dependencies>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>${quartz.version}</version>
</dependency>
</dependencies>
Quartz配置文件
quartz.properties配置如下:
# suppress inspection "UnusedProperty" for whole file
#ThreadPool 实现的类名
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 线程数,最多可同时跑多少个定时任务,20
org.quartz.threadPool.threadCount = 20
#线程优先级
org.quartz.threadPool.threadPriority = 5
#自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
org.quartz.jobStore.useProperties = true
# 集群配置
#激活集群
org.quartz.jobStore.isClustered = true
# 使用StdSchedulerFactory的 getScheduler()方法创建的scheduler实例名称
# 在同一个程序中可以根据该名称来区分scheduler,如果实在集群环境中使用,你必须使用同一个名称——集群环境下”逻辑”相同的scheduler,
# 默认为QuartzScheduler,此值对应SCHED_NAME字段值
org.quartz.scheduler.instanceName = QuartzScheduler
# scheduler实例的标志id,必须是全局唯一的,
# 即使在集群环境中”逻辑”相同的scheduler。 或者可以使用“SYS_PROP”通过系统属性设置id。
org.quartz.scheduler.instanceId = AUTO
#调度实例失效的检查时间间隔,200秒
org.quartz.jobStore.clusterCheckinInterval = 200000
#容许的最大作业延长时间,20小时
org.quartz.jobStore.misfireThreshold = 72000000
# Using RAMJobStore
## 如果使用RAMJobStore,请确认以下内容
## - org.quartz.jobStore.tablePrefix,
## - org.quartz.jobStore.driverDelegateClass,
## - org.quartz.jobStore.dataSource
## 所有 Quartz的数据,例如任务和触发器的数据都存放到内存中(而不是数据库中)。
# 即使你使用了数据库同时也使用了 Quartz,也建议使用 RamJobStore。
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
## Be sure to run the appropriate script(under docs/dbTables) first to create tables
## 数据保存方式为持久化 Using JobStoreTX
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# Configuring JDBCJobStore with the Table Prefix 表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
# Using DriverDelegate数据库平台
#org.quartz.jobStore.driverDelegateClass = org.quartz.jobStore.driverDelegateClass
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
# Using datasource
## 数据库别名 随便取
org.quartz.jobStore.dataSource = qzDS
# Define the datasource to use 数据库连接配置
#设置数据源
# org.quartz.dataSource.qzDS.jndiURL = CT
# 数据库Driver
org.quartz.dataSource.qzDS.driver = oracle.jdbc.driver.OracleDriver
# 数据库URL
org.quartz.dataSource.qzDS.URL = jdbc:oracle:thin:@//192.168.1.1:1521/orcl
# 数据库用户名
org.quartz.dataSource.qzDS.user = username
# 数据库密码
org.quartz.dataSource.qzDS.password = password
# 数据库最大连接数
org.quartz.dataSource.qzDS.maxConnections = 30
初始化SchedulerFactory
quartz.properties默认配置在classpath目录下通过
SchedulerFactory schedulerFactory = new StdSchedulerFactory()
初始化SchedulerFactory,但是可以通过自定义配置文件路径读取转换为Properties进行初始化SchedulerFactory,如下
Properties quartzProperties = PropertiesUtil.getProperties("quartz.properties");
SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties);
Oracle数据表
DROP TABLE QRTZ_FIRED_TRIGGERS;
DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE QRTZ_SCHEDULER_STATE;
DROP TABLE QRTZ_LOCKS;
DROP TABLE QRTZ_SIMPLE_TRIGGERS;
DROP TABLE QRTZ_SIMPROP_TRIGGERS;
DROP TABLE QRTZ_CRON_TRIGGERS;
DROP TABLE QRTZ_BLOB_TRIGGERS;
DROP TABLE QRTZ_TRIGGERS;
DROP TABLE QRTZ_JOB_DETAILS;
DROP TABLE QRTZ_CALENDARS;
-- 存储每一个已配置的 Job 的详细信息
CREATE TABLE qrtz_job_details
(
SCHED_NAME VARCHAR2(120) NOT NULL,
JOB_NAME VARCHAR2(200) NOT NULL,
JOB_GROUP VARCHAR2(200) NOT NULL,
DESCRIPTION VARCHAR2(250) NULL,
JOB_CLASS_NAME VARCHAR2(250) NOT NULL,
IS_DURABLE VARCHAR2(1) NOT NULL,
IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
JOB_DATA BLOB NULL,
CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
-- 存储已配置的 Trigger 的信息
CREATE TABLE qrtz_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
JOB_NAME VARCHAR2(200) NOT NULL,
JOB_GROUP VARCHAR2(200) NOT NULL,
DESCRIPTION VARCHAR2(250) NULL,
NEXT_FIRE_TIME NUMBER(13) NULL,
PREV_FIRE_TIME NUMBER(13) NULL,
PRIORITY NUMBER(13) NULL,
TRIGGER_STATE VARCHAR2(16) NOT NULL,
TRIGGER_TYPE VARCHAR2(8) NOT NULL,
START_TIME NUMBER(13) NOT NULL,
END_TIME NUMBER(13) NULL,
CALENDAR_NAME VARCHAR2(200) NULL,
MISFIRE_INSTR NUMBER(2) NULL,
JOB_DATA BLOB NULL,
CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
-- 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
CREATE TABLE qrtz_simple_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
REPEAT_COUNT NUMBER(7) NOT NULL,
REPEAT_INTERVAL NUMBER(12) NOT NULL,
TIMES_TRIGGERED NUMBER(10) NOT NULL,
CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
-- 存储 Cron Trigger,包括 Cron 表达式和时区信息
CREATE TABLE qrtz_cron_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
CRON_EXPRESSION VARCHAR2(120) NOT NULL,
TIME_ZONE_ID VARCHAR2(80),
CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE qrtz_simprop_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
STR_PROP_1 VARCHAR2(512) NULL,
STR_PROP_2 VARCHAR2(512) NULL,
STR_PROP_3 VARCHAR2(512) NULL,
INT_PROP_1 NUMBER(10) NULL,
INT_PROP_2 NUMBER(10) NULL,
LONG_PROP_1 NUMBER(13) NULL,
LONG_PROP_2 NUMBER(13) NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR2(1) NULL,
BOOL_PROP_2 VARCHAR2(1) NULL,
CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
-- Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,<span style="color:#800080;">JobStore</span> 并不知道如何存储实例的时候)
CREATE TABLE qrtz_blob_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
BLOB_DATA BLOB NULL,
CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
-- 以 Blob 类型存储 Quartz 的 Calendar 信息
CREATE TABLE qrtz_calendars
(
SCHED_NAME VARCHAR2(120) NOT NULL,
CALENDAR_NAME VARCHAR2(200) NOT NULL,
CALENDAR BLOB NOT NULL,
CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
-- 存储已暂停的 Trigger 组的信息
CREATE TABLE qrtz_paused_trigger_grps
(
SCHED_NAME VARCHAR2(120) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
-- 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息
CREATE TABLE qrtz_fired_triggers
(
SCHED_NAME VARCHAR2(120) NOT NULL,
ENTRY_ID VARCHAR2(95) NOT NULL,
TRIGGER_NAME VARCHAR2(200) NOT NULL,
TRIGGER_GROUP VARCHAR2(200) NOT NULL,
INSTANCE_NAME VARCHAR2(200) NOT NULL,
FIRED_TIME NUMBER(13) NOT NULL,
SCHED_TIME NUMBER(13) NOT NULL,
PRIORITY NUMBER(13) NOT NULL,
STATE VARCHAR2(16) NOT NULL,
JOB_NAME VARCHAR2(200) NULL,
JOB_GROUP VARCHAR2(200) NULL,
IS_NONCONCURRENT VARCHAR2(1) NULL,
REQUESTS_RECOVERY VARCHAR2(1) NULL,
CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
-- 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
CREATE TABLE qrtz_scheduler_state
(
SCHED_NAME VARCHAR2(120) NOT NULL,
INSTANCE_NAME VARCHAR2(200) NOT NULL,
LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
CHECKIN_INTERVAL NUMBER(13) NOT NULL,
CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
-- 存储程序的悲观锁的信息(假如使用了悲观锁)
CREATE TABLE qrtz_locks
(
SCHED_NAME VARCHAR2(120) NOT NULL,
LOCK_NAME VARCHAR2(40) NOT NULL,
CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
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);
QuartzManager管理类
public class QuartzManager {
private final static Logger LOGGER = LoggerFactory.getLogger(QuartzManager.class);
private static Properties quartzProperties = PropertiesUtil.getProperties("quartz.properties");
public static SchedulerFactory schedulerFactory;
static {
try {
schedulerFactory = new StdSchedulerFactory(quartzProperties);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param cron 时间设置,参考quartz说明文档
* @Description 添加一个定时任务
* @Description: 添加一个定时任务
*/
public static boolean addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron) {
boolean result = false;
try {
Scheduler scheduler = schedulerFactory.getScheduler(); // 任务名,任务组,任务执行类
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing());
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置JobDetail和Trigger
scheduler.scheduleJob(jobDetail, trigger);
LOGGER.info("JOB【{}】创建成功", jobName);
result = true;
} catch (Exception e) {
result = false;
LOGGER.error("ERROR:调度平台-新增一个定时任务【{}】失败!", jobName, e);
}
return result;
}
/**
* @param jobName Job名
* @param jobGroupName job的组名称
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cron 时间设置,参考quartz说明文档
* @Description 修改定时调度频率
* @Description: 修改一个任务的触发时间
*/
public static void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
/** 方式一 :调用 rescheduleJob 开始 */
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing());
// 创建Trigger对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
sched.rescheduleJob(triggerKey, trigger);
/** 方式一 :调用 rescheduleJob 结束 */
/** 方式二:先删除,然后在创建一个新的Job */
//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
//Class<? extends Job> jobClass = jobDetail.getJobClass();
//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的Job */
}
} catch (Exception e) {
LOGGER.error("ERROR:调度平台-修改定时任务【{}】失败!", jobName, e);
throw new RuntimeException(e);
}
}
/**
* @param jobName Job名
* @param jobGroupName job的组名称
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @Description 删除移除一个定时任务
*/
public static boolean removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
boolean result = false;
try {
Scheduler scheduler = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
LOGGER.info("JOB【{}】删除成功", jobName);
result = true;
} catch (Exception e) {
LOGGER.error("ERROR:调度平台-删除定时任务【{}】失败!", jobName, e);
}
return result;
}
/**
* @Description:启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (Exception e) {
LOGGER.error("ERROR:调度平台-关闭定时调度失败!", e);
throw new RuntimeException(e);
}
}
定时任务JOB类
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
public class TestJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
JobKey key = context.getJobDetail().getKey();
JobDataMap dataMap = context.getMergedJobDataMap();
....
System.out.println("启动定时调度:【 " + key + "】成功");
}
}
添加一个定时任务
public class JobStoreRunner{
/**
* 测试:创建一个定时任务
*
* @throws SchedulerException
*/
public void taskTest() throws SchedulerException {
// 获取Scheduler实例
Scheduler scheduler = QuartzManager.schedulerFactory.getScheduler();
JobDetail job = JobBuilder.newJob(TestJob.class).withIdentity("job2", "group2").build();
// 触发时间点
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 * * * * ? *");
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger2", "group2")
.withSchedule(cronScheduleBuilder)
.usingJobData("jobSays", "Hello World1111111111111111!")
.usingJobData("myFloatValue", 3.14122222222222f)
.usingJobData("myStateData", String.valueOf(new ArrayList())).build();
// 交由Scheduler安排触发
scheduler.scheduleJob(job, trigger);
// 关闭Scheduler
//scheduler.shutdown();
}
/**
* 启动增量调度的入口方法
*/
public static void main(String[] args) {
try {
JobStoreRunner qRunner = new JobStoreRunner();
qRunner.taskTest();
} catch (Exception var2) {
LOGGER.error("启动定时调度器失败!!!");
var2.printStackTrace();
}
}
}
启动定时调度
/**
* 启动定时调度
*/
public void task() {
QuartzManager.startJobs();
}