在项目开发过程中需要用到定时任务,由于业务需求,定时任务需要满足以下条件:
综合业务需要选择了集成Quartz
1.什么是quartz框架?
quartz是一个功能丰富的开源的任务调用系统,功能强大,可以让你的程序在指定时间执行,也可以按照某一个频度执行,,它可以创建简单或者复杂的几十、几百、甚至成千上万的job。在添加定时任务时可以携带参数,并且支持定时任务的动态更新。
2.quartz体系结构?
quartz框架主要核心组件包括调度器、触发器、作业。调度器作为作业的总指挥,触发器作为作业的操作者,作业为应用的功能模块。其关系如下图所示:
Job为作业的接口,为任务调度的对象;JobDetail用来描述Job的实现类及其它相关的静态信息;Trigger做为作业的定时管理工具,一个Trigger只能对应一个作业实例,而一个作业实例可对应多个触发器;Scheduler做为定时任务容器,是quartz最上层的东西,它提携了所有触发器和作业,使它们协调工作,每个Scheduler都存有JobDetail和Trigger的注册,一个Scheduler中可以注册多个JobDetail和多个Trigger。
源码地址:
https://github.com/prettycharacter/boot-quartz.git
1.spring-boot2.0继承了quartz,只需要引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2.添加配置文件
#quartz定时任务
#初始化表结构
spring.quartz.jdbc.initialize-schema = never
##集群只在存储方式是jobstore才有效
spring.quartz.job-store-type=jdbc
##同样名字的job在插入到表中会报错,设置为true会覆盖之前相同名字的job
spring.quartz.overwrite-existing-jobs=true
#选择quartz的事务,其通过JobStoreTX来管理
spring.quartz.properties.org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
##配置集群的话,必须实例名一样
spring.quartz.properties.org.quartz.scheduler.instanceName = MyClusteredScheduler
#本地启动时,若不想跑线上的定时可以用这个集群实例。不用修改实例名直接使用
#spring.quartz.properties.org.quartz.scheduler.instanceName = Local_ClusteredScheduler
##根据主机以及时间戳生成实例id
spring.quartz.properties.org.quartz.scheduler.instanceId = AUTO
#SimpleThreadPool是Quartz.Net中自带的线程池,默认个数为10个,代表一个Scheduler同一时刻并发的最多只能执行10个job,超过10个的job需要排队等待。
spring.quartz.properties.org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# threadCount和threadPriority将以setter的形式注入ThreadPool实例
# 并发个数 如果你只有几个工作每天触发几次 那么1个线程就可以,如果你有成千上万的工作,每分钟都有很多工作 那么久需要50-100之间.
# 只有1到100之间的数字是非常实用的
spring.quartz.properties.org.quartz.threadPool.threadCount = 50
##mysql使用的驱动代理
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
##开启集群配置
spring.quartz.properties.org.quartz.jobStore.isClustered=true
##调整for update强制走主库
spring.quartz.properties.org.quartz.jobStore.selectWithLockSQL=SELECT /*master*/ * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE
#调用是为了通知SchedulerPlugin它应该释放它的所有资源,该插件捕获 JVM 终止的事件(例如在 CRTL-C 上)并告诉 scheuler 关闭。
spring.quartz.properties.org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
spring.quartz.properties.org.quartz.plugin.shutdownHook.cleanShutdown=TRUE
3.初始化数据库表 11个
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;
-- ----------------------------
-- Table structure for qrtz_job_details
-- ----------------------------
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,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB COMMENT = '自定义触发器';
-- ----------------------------
-- Table structure for qrtz_triggers
-- ----------------------------
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 '作业名称',
JOB_GROUP VARCHAR(200) NOT NULL COMMENT '作业组',
DESCRIPTION VARCHAR(250) NULL COMMENT '描述',
NEXT_FIRE_TIME BIGINT(13) NULL COMMENT '下次执行时间',
PREV_FIRE_TIME BIGINT(13) NULL COMMENT '前一次执行时间',
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 '作业数据',
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 = '触发器的基本信息';
-- ----------------------------
-- Table structure for qrtz_simple_triggers
-- ----------------------------
CREATE TABLE `qrtz_simple_triggers` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
TRIGGER_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
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 = '存储简单的Trigger,包括重复次数,间隔,以及已触的次数';
-- ----------------------------
-- Table structure for qrtz_cron_triggers
-- ----------------------------
CREATE TABLE `qrtz_cron_triggers`(
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
TRIGGER_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
CRON_EXPRESSION VARCHAR(120) NOT NULL COMMENT '时间表达式',
TIME_ZONE_ID VARCHAR(80) COMMENT '时区ID',
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 Trigger,包括Cron表达式和时区信息';
-- ----------------------------
-- Table structure for qrtz_simprop_triggers
-- ----------------------------
CREATE TABLE `qrtz_simprop_triggers` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
TRIGGER_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
STR_PROP_1 VARCHAR(512) NULL COMMENT '根据不同的trigger类型存放各自的参数',
STR_PROP_2 VARCHAR(512) NULL COMMENT '根据不同的trigger类型存放各自的参数',
STR_PROP_3 VARCHAR(512) NULL COMMENT '根据不同的trigger类型存放各自的参数',
INT_PROP_1 INT NULL COMMENT '根据不同的trigger类型存放各自的参数',
INT_PROP_2 INT NULL COMMENT '根据不同的trigger类型存放各自的参数',
LONG_PROP_1 BIGINT NULL COMMENT '根据不同的trigger类型存放各自的参数',
LONG_PROP_2 BIGINT NULL COMMENT '根据不同的trigger类型存放各自的参数',
DEC_PROP_1 NUMERIC(13, 4) NULL COMMENT '根据不同的trigger类型存放各自的参数',
DEC_PROP_2 NUMERIC(13, 4) NULL COMMENT '根据不同的trigger类型存放各自的参数',
BOOL_PROP_1 VARCHAR(1) NULL COMMENT '根据不同的trigger类型存放各自的参数',
BOOL_PROP_2 VARCHAR(1) 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 '存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种类型的触发器';
-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
CREATE TABLE `qrtz_blob_triggers` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
TRIGGER_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
BLOB_DATA BLOB NULL COMMENT '保存triggers 一些信息',
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 COMMENT '自定义触发器';
-- ----------------------------
-- Table structure for qrtz_calendars
-- ----------------------------
CREATE TABLE `qrtz_calendars` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
CALENDAR_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME, CALENDAR_NAME)
) ENGINE = InnoDB COMMENT '以 Blob 类型存储 Quartz 的 Calendar 信息';
-- ----------------------------
-- Table structure for qrtz_paused_trigger_grps
-- ----------------------------
CREATE TABLE `qrtz_paused_trigger_grps` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP)
) ENGINE = InnoDB COMMENT '存储已暂停的 Trigger组的信息';
-- ----------------------------
-- Table structure for qrtz_fired_triggers
-- ----------------------------
CREATE TABLE `qrtz_fired_triggers` (
SCHED_NAME VARCHAR(120) NOT NULL COMMENT '计划名称',
ENTRY_ID VARCHAR(95) NOT NULL COMMENT '组标识',
TRIGGER_NAME VARCHAR(200) NOT NULL COMMENT '触发器名称',
TRIGGER_GROUP VARCHAR(200) NOT NULL COMMENT '触发器组',
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 '存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息';
-- ----------------------------
-- Table structure for qrtz_scheduler_state
-- ----------------------------
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 '存储少量的有关 Scheduler 的状态信息,和别的Scheduler实例(假如是用于一个集群中)';
-- ----------------------------
-- Table structure for qrtz_locks
-- ----------------------------
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 '存储程序的悲观锁的信息(假如使用了悲观锁)';
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);
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(200) NOT NULL,
JOB_GROUP VARCHAR(200) 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(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) 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(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) 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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) 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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP)
)
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) 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(200) 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(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) 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(200) NULL,
JOB_GROUP VARCHAR(200) 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(200) 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);
4.创建Job类,触发定时任务后执行的操作
package cn.sr.cjwm.support.task;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* @author: XuPengfei
* @data: 2020/7/10 23 01
* @description:
*/
public class TestTask extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("正在执行" + jobExecutionContext.getMergedJobDataMap().get("sss"));
}
}
5.QuartzManager,java来进行定时任务的增删改查的操作。
package cn.sr.cjwm.support.util;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* @author: xpf
* @data: 2020/7/10
* @description:
*/
@Component
public class QuartzManager {
private static QuartzManager jobUtil;
@Autowired
private Scheduler scheduler;
public QuartzManager() {
jobUtil = this;
}
public static QuartzManager getInstance() {
return QuartzManager.jobUtil;
}
/**
* 创建job
*
* @param clazz 任务类
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @param cronExpression cron表达式
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void addJob(Class clazz, String jobName, String jobGroupName, String cronExpression) throws Exception {
// 启动调度器
System.out.println(scheduler);
scheduler.start();
//构建job信息
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobName, jobGroupName).build();
//表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
}
/**
* 创建job,可传参
*
* @param clazz 任务类
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @param cronExpression cron表达式
* @param argMap map形式参数
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void addJob(Class clazz, String jobName, String jobGroupName, String cronExpression, Map<String, Object> argMap) throws Exception {
// 启动调度器
scheduler.start();
//构建job信息
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobName, jobGroupName).build();
//表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(scheduleBuilder).build();
//获得JobDataMap,写入数据
trigger.getJobDataMap().putAll(argMap);
scheduler.scheduleJob(jobDetail, trigger);
}
/**
* 暂停job
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @throws SchedulerException
* @author xpf
* @date 2018/5/30.
*/
public void pauseJob(String jobName, String jobGroupName) throws SchedulerException {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* 恢复job
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @throws SchedulerException
* @author xpf
* @date 2018/5/30.
*/
public void resumeJob(String jobName, String jobGroupName) throws SchedulerException {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* job 更新,只更新频率
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @param cronExpression cron表达式
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void updateJob(String jobName, String jobGroupName, String cronExpression) throws Exception {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
/**
* job 更新,更新频率和参数
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @param cronExpression cron表达式
* @param argMap 参数
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void updateJob(String jobName, String jobGroupName, String cronExpression, Map<String, Object> argMap) throws Exception {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//修改map
trigger.getJobDataMap().putAll(argMap);
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
/**
* job 更新,只更新更新参数
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @param argMap 参数
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void updateJob(String jobName, String jobGroupName, Map<String, Object> argMap) throws Exception {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//修改map
trigger.getJobDataMap().putAll(argMap);
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
/**
* job 删除
*
* @param jobName 任务名称
* @param jobGroupName 任务所在组名称
* @throws Exception
* @author xpf
* @date 2018/5/30.
*/
public void deleteJob(String jobName, String jobGroupName) throws Exception {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* 启动所有定时任务
*
* @author xpf
* @date 2018/5/30.
*/
public void startAllJobs() {
try {
scheduler.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 关闭所有定时任务
*
* @author xpf
* @date 2018/5/30.
*/
public void shutdownAllJobs() {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取所有任务列表
*
* @return
* @throws SchedulerException
*/
public List<Map<String, Object>> getAllJob() throws SchedulerException {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<Map<String, Object>> jobList = new ArrayList<>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> job = new HashMap<>();
job.put("jobName", jobKey.getName());
job.put("jobGroupName", jobKey.getGroup());
job.put("trigger", trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.put("cronExpression", cronExpression);
}
jobList.add(job);
}
}
return jobList;
}
}
5.创建测试类触发定时任务。
package cn.sr.cjwm.support.controller;
import cn.sr.cjwm.common.pojo.request.RequestData;
import cn.sr.cjwm.support.task.TestTask;
import cn.sr.cjwm.support.util.QuartzManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author: XuPengfei
* @data: 2020/7/10 22 59
* @description:
*/
@RestController
@RequestMapping("/test")
@Api(tags = "时间测试")
@Slf4j
public class TestController {
/**
* @Description:
* @Param: * @param null
* @return:
* @Author: xpf
* @date: 2020/7/10
*/
@PostMapping("addquartz")
@ApiOperation(value = "新增定时任务 xpf")
public void addQuartz(@RequestBody RequestData<String> requestData, HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("sss", requestData.getReqData());
try {
QuartzManager.getInstance().addJob(TestTask.class, "test1", "test", "00 20 23 10 7 ? 2020", map);
} catch (Exception e) {
e.printStackTrace();
}
}
}