From dadb66c8e9f8126bae13f9d6d0a4a578379a4d52 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 13 Feb 2021 22:52:42 +0800 Subject: [PATCH] 初始化 Quartz 的整体代码 --- sql/quartz.sql | 350 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java | 12 ++++++++++++ src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java | 21 +++++++++++++++++++++ src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java | 97 ------------------------------------------------------------------------------------------------- src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java | 89 ----------------------------------------------------------------------------------------- src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/resources/application.yaml | 29 +++++++++++++++++++++++++++++ 10 files changed, 552 insertions(+), 356 deletions(-) create mode 100644 src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java delete mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java delete mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java create mode 100644 src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java diff --git a/sql/quartz.sql b/sql/quartz.sql index 52b6a09..dca0859 100644 --- a/sql/quartz.sql +++ b/sql/quartz.sql @@ -1,170 +1,180 @@ --- ---------------------------- --- 1、存储每一个已配置的 jobDetail 的详细信息 --- ---------------------------- -drop table if exists QRTZ_JOB_DETAILS; -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; - --- ---------------------------- --- 2、 存储已配置的 Trigger 的信息 --- ---------------------------- -drop table if exists QRTZ_TRIGGERS; -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), - foreign key (sched_name,job_name,job_group) references QRTZ_JOB_DETAILS(sched_name,job_name,job_group) -) engine=innodb; - --- ---------------------------- --- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数 --- ---------------------------- -drop table if exists QRTZ_SIMPLE_TRIGGERS; -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), - foreign key (sched_name,trigger_name,trigger_group) references QRTZ_TRIGGERS(sched_name,trigger_name,trigger_group) -) engine=innodb; - --- ---------------------------- --- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息 --- ---------------------------- -drop table if exists QRTZ_CRON_TRIGGERS; -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(200) 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; - --- ---------------------------- --- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候) --- ---------------------------- -drop table if exists QRTZ_BLOB_TRIGGERS; -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), - foreign key (sched_name,trigger_name,trigger_group) references QRTZ_TRIGGERS(sched_name,trigger_name,trigger_group) -) engine=innodb; - --- ---------------------------- --- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围 --- ---------------------------- -drop table if exists QRTZ_CALENDARS; -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; - --- ---------------------------- --- 7、 存储已暂停的 Trigger 组的信息 --- ---------------------------- -drop table if exists QRTZ_PAUSED_TRIGGER_GRPS; -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; - --- ---------------------------- --- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息 --- ---------------------------- -drop table if exists QRTZ_FIRED_TRIGGERS; -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; - --- ---------------------------- --- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例 --- ---------------------------- -drop table if exists QRTZ_SCHEDULER_STATE; -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; - --- ---------------------------- --- 10、 存储程序的悲观锁的信息(假如使用了悲观锁) --- ---------------------------- -drop table if exists QRTZ_LOCKS; -create table QRTZ_LOCKS ( - sched_name varchar(120) not null, - lock_name varchar(40) not null, - primary key (sched_name,lock_name) -) engine=innodb; - -drop table if exists QRTZ_SIMPROP_TRIGGERS; -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), - foreign key (sched_name,trigger_name,trigger_group) references QRTZ_TRIGGERS(sched_name,trigger_name,trigger_group) -) engine=innodb; - -commit; \ No newline at end of file + +# +# In your Quartz properties file, you'll need to set +# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate +# +# +# By: Ron Cordell - roncordell +# I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM. + +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; diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java new file mode 100644 index 0000000..53fad1c --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java @@ -0,0 +1,12 @@ +package cn.iocoder.dashboard.framework.quartz.core.enums; + +/** + * Quartz Job Data 的 key 枚举 + */ +public enum JobDataKeyEnum { + + JOB_ID, + JOB_HANDLER_NAME, + JOB_HANDLER_PARAM + +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java new file mode 100644 index 0000000..4f5b3d9 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.dashboard.framework.quartz.core.handler; + +import cn.iocoder.dashboard.common.pojo.CommonResult; + +/** + * 任务处理器 + * + * @author 芋道源码 + */ +public interface JobHandler { + + /** + * 执行任务 + * + * @param param 参数 + * @return 结果 + * @throws Exception 异常 + */ + CommonResult execute(String param) throws Exception; + +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java new file mode 100644 index 0000000..8989475 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java @@ -0,0 +1,49 @@ +package cn.iocoder.dashboard.framework.quartz.core.handler; + +import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.quartz.PersistJobDataAfterExecution; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import javax.annotation.Resource; + +/** + * 基础 Job 调用者,负责调用 {@link JobHandler#execute(String)} 执行任务 + * + * @author 芋道源码 + */ +@PersistJobDataAfterExecution +@DisallowConcurrentExecution +public class JobHandlerInvoker extends QuartzJobBean { + + @Resource + private ApplicationContext applicationContext; + + @Override + protected void executeInternal(JobExecutionContext executionContext) { + // 获得 JobHandler 对象 + String jobHandlerName = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_NAME); + JobHandler jobHandler = applicationContext.getBean(jobHandlerName, JobHandler.class); + + // 执行任务 + String jobParam = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_PARAM); + try { + jobHandler.execute(jobParam); + } catch (Exception e) { + // TODO 需要后续处理 + } + } + + @SuppressWarnings("SwitchStatementWithTooFewBranches") + private static String getJobData(JobExecutionContext executionContext, JobDataKeyEnum key) { + switch (key) { + case JOB_ID: + return executionContext.getJobDetail().getJobDataMap().getString(key.name()); + default: + return executionContext.getTrigger().getJobDataMap().getString(key.name()); + } + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java new file mode 100644 index 0000000..7223374 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java @@ -0,0 +1,75 @@ +package cn.iocoder.dashboard.framework.quartz.core.scheduler; + +import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum; +import cn.iocoder.dashboard.framework.quartz.core.handler.JobHandlerInvoker; +import org.quartz.*; + +/** + * {@link org.quartz.Scheduler} 的管理器,负责创建任务 + * + * @author 芋道源码 + */ +public class SchedulerManager { + + private final Scheduler scheduler; + + public SchedulerManager(Scheduler scheduler) { + this.scheduler = scheduler; + } + + public void addJob(Long jobId, String jobHandlerName, String jobHandlerParam, + String triggerName, String cronExpression) + throws SchedulerException { + // 创建 JobDetail 对象 + JobDetail jobDetail = JobBuilder.newJob(JobHandlerInvoker.class) + .usingJobData(JobDataKeyEnum.JOB_ID.name(), jobId) + .withIdentity(jobHandlerName).build(); + // 创建 Trigger 对象 + Trigger trigger = TriggerBuilder.newTrigger() + .withIdentity(triggerName) + .usingJobData(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName) + .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam) + .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) + .build(); + // 新增调度 + scheduler.scheduleJob(jobDetail, trigger); + } + + public void updateJob(String jobHandlerName, String jobHandlerParam, + String triggerName, String cronExpression) throws SchedulerException { + // 创建 Trigger 对象 + Trigger trigger = TriggerBuilder.newTrigger() + .withIdentity(triggerName) + .usingJobData(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName) + .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam) + .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) + .build(); + // 修改调度 + scheduler.rescheduleJob(new TriggerKey(triggerName), trigger); + } + + public void deleteJob(String jobHandlerName) throws SchedulerException { + scheduler.deleteJob(new JobKey(jobHandlerName)); + } + + public void pauseJob(String jobHandlerName) throws SchedulerException { + scheduler.pauseJob(new JobKey(jobHandlerName)); + } + + public void resumeJob(String jobHandlerName, + String triggerName) throws SchedulerException { + scheduler.resumeJob(new JobKey(jobHandlerName)); + scheduler.resumeTrigger(new TriggerKey(triggerName)); + } + + public void triggerJob(Long jobId, String jobHandlerName, String jobHandlerParam) + throws SchedulerException { + JobDataMap data = new JobDataMap(); + data.put(JobDataKeyEnum.JOB_ID.name(), jobId); + data.put(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName); + data.put(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam); + // 触发任务 + scheduler.triggerJob(new JobKey(jobHandlerName), data); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java deleted file mode 100644 index 2120255..0000000 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java +++ /dev/null @@ -1,97 +0,0 @@ -package cn.iocoder.dashboard.modules.infra.dal.dataobject.job; - -import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 定时任务表 - * - * @author 芋道源码 - */ -@TableName("inf_job") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class InfJob extends BaseDO { - - /** - * 任务编号 - */ - @TableId - private Long id; - /** - * 任务名称 - */ - private String name; - /** - * 任务分组 - */ - @TableField("`group`") - private String group; - /** - * 任务状态 - * - * 枚举 {@link InfJobStatusEnum} - */ - private Integer status; - /** - * 处理器的名字 - */ - private String handlerName; - /** - * 处理器的参数 - */ - private String handlerParam; - - // ========== 时间相关字段 ========== - - /** - * CRON 表达式 - */ - private String cronExpression; - /** - * 最后一次执行的开始时间 - * - * 该字段在任务执行结束后,进行记录 - */ - private Date executeBeginTime; - /** - * 最后一次执行的结束时间 - * - * 该字段在任务执行结束后,进行记录 - */ - private Date executeEndTime; - /** - * 上一次触发时间,来自 Quartz SCHE_TRIGGERS 表 - */ - private Date firePrevTime; - /** - * 下一次触发时间,来自 Quartz SCHE_TRIGGERS 表 - * - * 在触发器状态从 `ACQUIRED` 变成 `BLOCKED` 时,就会更新 PREV_FIRE_TIME、NEXT_FIRE_TIME,然后定时任务才正式开始执行 - */ - private Date fireNextTime; - - // ========== 监控相关字段 ========== - /** - * 监控开关 - */ - private Boolean monitorSwitch; - /** - * 监控超时时间,单位:毫秒 - */ - private Integer monitorTimeout; - - // TODO misfirePolicy - // TODO concurrent - // TODO 失败重试 - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java new file mode 100644 index 0000000..013a390 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java @@ -0,0 +1,97 @@ +package cn.iocoder.dashboard.modules.infra.dal.dataobject.job; + +import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +/** + * 定时任务 DO + * + * @author 芋道源码 + */ +@TableName("inf_job") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobDO extends BaseDO { + + /** + * 任务编号 + */ + @TableId + private Long id; + /** + * 任务名称 + */ + private String name; + /** + * 任务分组 + */ + @TableField("`group`") + private String group; + /** + * 任务状态 + * + * 枚举 {@link InfJobStatusEnum} + */ + private Integer status; + /** + * 处理器的名字 + */ + private String handlerName; + /** + * 处理器的参数 + */ + private String handlerParam; + + // ========== 时间相关字段 ========== + + /** + * CRON 表达式 + */ + private String cronExpression; + /** + * 最后一次执行的开始时间 + * + * 该字段在任务执行结束后,进行记录 + */ + private Date executeBeginTime; + /** + * 最后一次执行的结束时间 + * + * 该字段在任务执行结束后,进行记录 + */ + private Date executeEndTime; + /** + * 上一次触发时间,来自 Quartz SCHE_TRIGGERS 表 + */ + private Date firePrevTime; + /** + * 下一次触发时间,来自 Quartz SCHE_TRIGGERS 表 + * + * 在触发器状态从 `ACQUIRED` 变成 `BLOCKED` 时,就会更新 PREV_FIRE_TIME、NEXT_FIRE_TIME,然后定时任务才正式开始执行 + */ + private Date fireNextTime; + + // ========== 监控相关字段 ========== + /** + * 监控开关 + */ + private Boolean monitorSwitch; + /** + * 监控超时时间,单位:毫秒 + */ + private Integer monitorTimeout; + + // TODO misfirePolicy + // TODO concurrent + // TODO 失败重试 + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java deleted file mode 100644 index 7ba95ed..0000000 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java +++ /dev/null @@ -1,89 +0,0 @@ -package cn.iocoder.dashboard.modules.infra.dal.dataobject.job; - -import cn.iocoder.dashboard.common.pojo.CommonResult; -import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 定时任务的执行日志 sys_job_log - * - * @author 芋道源码 - */ -@TableName("inf_job_log") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class InfJobLog extends BaseDO { - - /** - * 日志编号 - */ - private Long id; - /** - * 任务编号 - * - * 关联 {@link InfJob#getId()} - */ - private Long jobId; - /** - * 任务名称 - * - * 冗余字段 {@link InfJob#getName()} - */ - private String jobName; - /** - * 任务分组 - * - * 冗余字段 {@link InfJob#getGroup()} - */ - private String jobGroup; - /** - * 处理器的名字 - * - * 冗余字段 {@link InfJob#getHandlerName()} - */ - private String handlerName; - /** - * 处理器的参数 - * - * 冗余字段 {@link InfJob#getHandlerParam()} - */ - private String handlerParam; - - /** - * 开始执行时间 - */ - private Date startTime; - /** - * 结束执行时间 - */ - private Date endTime; - /** - * 执行时长,单位:毫秒 - */ - private Integer duration; - /** - * 结果码 - * - * 目前使用的 {@link CommonResult#getCode()} 属性 - */ - private Integer resultCode; - /** - * 结果提示 - * - * 目前使用的 {@link CommonResult#getMsg()} 属性 - */ - private String resultMsg; - /** - * 结果数据 - * - * 如果是对象,则使用 JSON 格式化 - */ - private String resultData; - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java new file mode 100644 index 0000000..c71d147 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java @@ -0,0 +1,89 @@ +package cn.iocoder.dashboard.modules.infra.dal.dataobject.job; + +import cn.iocoder.dashboard.common.pojo.CommonResult; +import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +/** + * 定时任务的执行日志 sys_job_log + * + * @author 芋道源码 + */ +@TableName("inf_job_log") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InfJobLogDO extends BaseDO { + + /** + * 日志编号 + */ + private Long id; + /** + * 任务编号 + * + * 关联 {@link InfJobDO#getId()} + */ + private Long jobId; + /** + * 任务名称 + * + * 冗余字段 {@link InfJobDO#getName()} + */ + private String jobName; + /** + * 任务分组 + * + * 冗余字段 {@link InfJobDO#getGroup()} + */ + private String jobGroup; + /** + * 处理器的名字 + * + * 冗余字段 {@link InfJobDO#getHandlerName()} + */ + private String handlerName; + /** + * 处理器的参数 + * + * 冗余字段 {@link InfJobDO#getHandlerParam()} + */ + private String handlerParam; + + /** + * 开始执行时间 + */ + private Date startTime; + /** + * 结束执行时间 + */ + private Date endTime; + /** + * 执行时长,单位:毫秒 + */ + private Integer duration; + /** + * 结果码 + * + * 目前使用的 {@link CommonResult#getCode()} 属性 + */ + private Integer resultCode; + /** + * 结果提示 + * + * 目前使用的 {@link CommonResult#getMsg()} 属性 + */ + private String resultMsg; + /** + * 结果数据 + * + * 目前使用的 {@link CommonResult#getData()} 数据 + */ + private String resultData; + +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f4e255c..6f184d6 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -42,6 +42,35 @@ spring: # main: # lazy-initialization: true # TODO 芋艿:本地开发环境,可以配置下 lazy 延迟加载 + # Quartz 配置项,对应 QuartzProperties 配置类 + quartz: + scheduler-name: clusteredScheduler # Scheduler 名字。默认为 schedulerName + job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。 + auto-startup: true # Quartz 是否自动启动 + startup-delay: 0 # 延迟 N 秒启动 + wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true + overwrite-existing-jobs: false # 是否覆盖已有 Job 的配置 + properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档 + org: + quartz: + # JobStore 相关配置 + jobStore: + # 数据源名称 +# dataSource: quartzDataSource # 使用的数据源 TODO 使用默认数据源 + class: org.quartz.impl.jdbcjobstore.JobStoreTX # JobStore 实现类 + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ # Quartz 表前缀 + isClustered: true # 是集群模式 + clusterCheckinInterval: 1000 + useProperties: false + # 线程池相关配置 + threadPool: + threadCount: 25 # 线程池大小。默认为 10 。 + threadPriority: 5 # 线程优先级 + class: org.quartz.simpl.SimpleThreadPool # 线程池类型 + jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置 + initialize-schema: never # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。 + # 芋道配置项,设置当前项目所有自定义的配置 yudao: info: -- libgit2 0.21.4