Springboot2.x+Quartz分布式集群的实现
生产环境一般都是多节点高可用,Springboot本身自带有定时任务功能,但我们项目需求要求能对定时任务进行增,删,改,查。所以考虑引进Quartz,引入Quartz就需要考虑分布式集群,所以就有了这篇文章。
数据库脚本
Quartz数据库有11张表,既支持Mysql,也支持Oracle
Mysql
/* NavicatMySQLDataTransfer SourceServer:10.19.34.3_ehr_admin SourceServerVersion:50639 SourceHost:10.19.34.3:3306 SourceDatabase:attend_base_dev TargetServerType:MYSQL TargetServerVersion:50639 FileEncoding:65001 Date:2020-08-2816:29:36 */ --SETFOREIGN_KEY_CHECKS=0; ------------------------------ --Tablestructurefor`qrtz_CALENDARS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_CALENDARS`; CREATETABLE`qrtz_CALENDARS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `CALENDAR_NAME`varchar(200)NOTNULL, `CALENDAR`blobNOTNULL, PRIMARYKEY(`SCHED_NAME`,`CALENDAR_NAME`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='日历信息'; ------------------------------ --Recordsofqrtz_CALENDARS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_FIRED_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_FIRED_TRIGGERS`; CREATETABLE`qrtz_FIRED_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `ENTRY_ID`varchar(95)NOTNULLCOMMENT'组标识', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `INSTANCE_NAME`varchar(200)NOTNULLCOMMENT'当前实例的名称', `FIRED_TIME`bigint(13)NOTNULLCOMMENT'当前执行时间', `SCHED_TIME`bigint(13)NOTNULLCOMMENT'计划时间', `PRIORITY`int(11)NOTNULLCOMMENT'权重', `STATE`varchar(16)NOTNULLCOMMENT'状态:WAITING:等待\r\nPAUSED:暂停\r\nACQUIRED:正常执行\r\nBLOCKED:阻塞\r\nERROR:错误', `JOB_NAME`varchar(200)DEFAULTNULLCOMMENT'作业名称', `JOB_GROUP`varchar(200)DEFAULTNULLCOMMENT'作业组', `IS_NONCONCURRENT`varchar(1)DEFAULTNULLCOMMENT'是否并行', `REQUESTS_RECOVERY`varchar(1)DEFAULTNULLCOMMENT'是否要求唤醒', PRIMARYKEY(`SCHED_NAME`,`ENTRY_ID`), KEY`IDX_qrtz_FT_TRIG_INST_NAME`(`SCHED_NAME`,`INSTANCE_NAME`), KEY`IDX_qrtz_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`), KEY`IDX_qrtz_FT_J_G`(`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY`IDX_qrtz_FT_JG`(`SCHED_NAME`,`JOB_GROUP`), KEY`IDX_qrtz_FT_T_G`(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY`IDX_qrtz_FT_TG`(`SCHED_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='保存已经触发的触发器状态信息'; ------------------------------ --Recordsofqrtz_FIRED_TRIGGERS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_JOB_DETAILS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_JOB_DETAILS`; CREATETABLE`qrtz_JOB_DETAILS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `JOB_NAME`varchar(200)NOTNULLCOMMENT'集群中job的名字', `JOB_GROUP`varchar(200)NOTNULLCOMMENT'集群中job的所属组的名字', `DESCRIPTION`varchar(250)DEFAULTNULLCOMMENT'描述', `JOB_CLASS_NAME`varchar(250)NOTNULLCOMMENT'作业程序类名', `IS_DURABLE`varchar(1)NOTNULLCOMMENT'是否持久', `IS_NONCONCURRENT`varchar(1)NOTNULLCOMMENT'是否并行', `IS_UPDATE_DATA`varchar(1)NOTNULLCOMMENT'是否更新', `REQUESTS_RECOVERY`varchar(1)NOTNULLCOMMENT'是否要求唤醒', `JOB_DATA`blob, PRIMARYKEY(`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY`IDX_qrtz_J_REQ_RECOVERY`(`SCHED_NAME`,`REQUESTS_RECOVERY`), KEY`IDX_qrtz_J_GRP`(`SCHED_NAME`,`JOB_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='job详细信息'; ------------------------------ --Recordsofqrtz_JOB_DETAILS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_LOCKS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_LOCKS`; CREATETABLE`qrtz_LOCKS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `LOCK_NAME`varchar(40)NOTNULLCOMMENT'锁名称', PRIMARYKEY(`SCHED_NAME`,`LOCK_NAME`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='存储程序的悲观锁的信息(假如使用了悲观锁)'; ------------------------------ --Recordsofqrtz_LOCKS ------------------------------ --Tablestructurefor`qrtz_PAUSED_TRIGGER_GRPS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_PAUSED_TRIGGER_GRPS`; CREATETABLE`qrtz_PAUSED_TRIGGER_GRPS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', PRIMARYKEY(`SCHED_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='存放暂停掉的触发器'; ------------------------------ --Recordsofqrtz_PAUSED_TRIGGER_GRPS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_SCHEDULER_STATE` ------------------------------ --DROPTABLEIFEXISTS`qrtz_SCHEDULER_STATE`; CREATETABLE`qrtz_SCHEDULER_STATE`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `INSTANCE_NAME`varchar(200)NOTNULLCOMMENT'实例名称', `LAST_CHECKIN_TIME`bigint(13)NOTNULLCOMMENT'最后的检查时间', `CHECKIN_INTERVAL`bigint(13)NOTNULLCOMMENT'检查间隔', PRIMARYKEY(`SCHED_NAME`,`INSTANCE_NAME`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='调度器状态'; ------------------------------ --Recordsofqrtz_SCHEDULER_STATE ------------------------------ --Tablestructurefor`qrtz_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_TRIGGERS`; CREATETABLE`qrtz_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `JOB_NAME`varchar(200)NOTNULLCOMMENT'作业名称', `JOB_GROUP`varchar(200)NOTNULLCOMMENT'作业组', `DESCRIPTION`varchar(250)DEFAULTNULLCOMMENT'描述', `NEXT_FIRE_TIME`bigint(13)DEFAULTNULLCOMMENT'下次执行时间', `PREV_FIRE_TIME`bigint(13)DEFAULTNULLCOMMENT'前一次', `PRIORITY`int(11)DEFAULTNULLCOMMENT'优先权', `TRIGGER_STATE`varchar(16)NOTNULLCOMMENT'触发器状态', `TRIGGER_TYPE`varchar(8)NOTNULLCOMMENT'触发器类型', `START_TIME`bigint(13)NOTNULLCOMMENT'开始时间', `END_TIME`bigint(13)DEFAULTNULLCOMMENT'结束时间', `CALENDAR_NAME`varchar(200)DEFAULTNULLCOMMENT'日历名称', `MISFIRE_INSTR`smallint(2)DEFAULTNULLCOMMENT'失败次数', `JOB_DATA`blob, PRIMARYKEY(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY`IDX_qrtz_T_J`(`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`), KEY`IDX_qrtz_T_JG`(`SCHED_NAME`,`JOB_GROUP`), KEY`IDX_qrtz_T_C`(`SCHED_NAME`,`CALENDAR_NAME`), KEY`IDX_qrtz_T_G`(`SCHED_NAME`,`TRIGGER_GROUP`), KEY`IDX_qrtz_T_STATE`(`SCHED_NAME`,`TRIGGER_STATE`), KEY`IDX_qrtz_T_N_STATE`(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`), KEY`IDX_qrtz_T_N_G_STATE`(`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`), KEY`IDX_qrtz_T_NEXT_FIRE_TIME`(`SCHED_NAME`,`NEXT_FIRE_TIME`), KEY`IDX_qrtz_T_NFT_ST`(`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`), KEY`IDX_qrtz_T_NFT_MISFIRE`(`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`), KEY`IDX_qrtz_T_NFT_ST_MISFIRE`(`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`), KEY`IDX_qrtz_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='触发器'; ------------------------------ --Recordsofqrtz_TRIGGERS ------------------------------ --Tablestructurefor`qrtz_SIMPLE_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_SIMPLE_TRIGGERS`; CREATETABLE`qrtz_SIMPLE_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `REPEAT_COUNT`bigint(7)NOTNULLCOMMENT'重复次数', `REPEAT_INTERVAL`bigint(12)NOTNULLCOMMENT'重复间隔', `TIMES_TRIGGERED`bigint(10)NOTNULLCOMMENT'触发次数', PRIMARYKEY(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='简单的触发器'; ------------------------------ --Recordsofqrtz_SIMPLE_TRIGGERS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_SIMPROP_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_SIMPROP_TRIGGERS`; CREATETABLE`qrtz_SIMPROP_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `STR_PROP_1`varchar(512)DEFAULTNULL, `STR_PROP_2`varchar(512)DEFAULTNULL, `STR_PROP_3`varchar(512)DEFAULTNULL, `INT_PROP_1`int(11)DEFAULTNULL, `INT_PROP_2`int(11)DEFAULTNULL, `LONG_PROP_1`bigint(20)DEFAULTNULL, `LONG_PROP_2`bigint(20)DEFAULTNULL, `DEC_PROP_1`decimal(13,4)DEFAULTNULL, `DEC_PROP_2`decimal(13,4)DEFAULTNULL, `BOOL_PROP_1`varchar(1)DEFAULTNULL, `BOOL_PROP_2`varchar(1)DEFAULTNULL, PRIMARYKEY(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种类型的触发器'; ------------------------------ --Recordsofqrtz_SIMPROP_TRIGGERS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_BLOB_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_BLOB_TRIGGERS`; CREATETABLE`qrtz_BLOB_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `BLOB_DATA`blob, PRIMARYKEY(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`), KEY`SCHED_NAME`(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='以Blob类型存储的触发器'; ------------------------------ --Recordsofqrtz_BLOB_TRIGGERS ------------------------------ ------------------------------ --Tablestructurefor`qrtz_CRON_TRIGGERS` ------------------------------ --DROPTABLEIFEXISTS`qrtz_CRON_TRIGGERS`; CREATETABLE`qrtz_CRON_TRIGGERS`( `SCHED_NAME`varchar(120)NOTNULLCOMMENT'计划名称', `TRIGGER_NAME`varchar(200)NOTNULLCOMMENT'触发器名称', `TRIGGER_GROUP`varchar(200)NOTNULLCOMMENT'触发器组', `CRON_EXPRESSION`varchar(120)NOTNULLCOMMENT'时间表达式', `TIME_ZONE_ID`varchar(80)DEFAULTNULLCOMMENT'时区IDnvarchar80', PRIMARYKEY(`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT='定时触发器'; ------------------------------ --Recordsofqrtz_CRON_TRIGGERS ------------------------------ Oracle createtableQRTZ_CALENDARS ( sched_nameVARCHAR2(120)notnull, calendar_nameVARCHAR2(200)notnull, calendarBLOBnotnull ); altertableQRTZ_CALENDARS addconstraintPK_QRTZ_CALENDARSprimarykey(SCHED_NAME,CALENDAR_NAME); createtableQRTZ_FIRED_TRIGGERS ( sched_nameVARCHAR2(120)notnull, entry_idVARCHAR2(95)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, instance_nameVARCHAR2(200)notnull, fired_timeNUMBER(13)notnull, sched_timeNUMBER(13)notnull, priorityINTEGERnotnull, stateVARCHAR2(16)notnull, job_nameVARCHAR2(200), job_groupVARCHAR2(200), is_nonconcurrentVARCHAR2(1), requests_recoveryVARCHAR2(1) ); altertableQRTZ_FIRED_TRIGGERS addconstraintPK_QRTZ_FIRED_TRIGGERSprimarykey(SCHED_NAME,ENTRY_ID); createtableQRTZ_JOB_DETAILS ( sched_nameVARCHAR2(120)notnull, job_nameVARCHAR2(200)notnull, job_groupVARCHAR2(200)notnull, descriptionVARCHAR2(250), job_class_nameVARCHAR2(250)notnull, is_durableVARCHAR2(1)notnull, is_nonconcurrentVARCHAR2(1)notnull, is_update_dataVARCHAR2(1)notnull, requests_recoveryVARCHAR2(1)notnull, job_dataBLOB ); altertableQRTZ_JOB_DETAILS addconstraintPK_QRTZ_JOB_DETAILSprimarykey(SCHED_NAME,JOB_NAME,JOB_GROUP); createtableQRTZ_LOCKS ( sched_nameVARCHAR2(120)notnull, lock_nameVARCHAR2(40)notnull ); altertableQRTZ_LOCKS addconstraintPK_QRTZ_LOCKSprimarykey(SCHED_NAME,LOCK_NAME); createtableQRTZ_PAUSED_TRIGGER_GRPS ( sched_nameVARCHAR2(120)notnull, trigger_groupVARCHAR2(200)notnull ); altertableQRTZ_PAUSED_TRIGGER_GRPS addconstraintPK__TRIGGER_GRPSprimarykey(SCHED_NAME,TRIGGER_GROUP); createtableQRTZ_SCHEDULER_STATE ( sched_nameVARCHAR2(120)notnull, instance_nameVARCHAR2(200)notnull, last_checkin_timeNUMBER(13)notnull, checkin_intervalNUMBER(13)notnull ); altertableQRTZ_SCHEDULER_STATE addconstraintPK_QRTZ_SCHEDULER_STATEprimarykey(SCHED_NAME,INSTANCE_NAME); createtableQRTZ_TRIGGERS ( sched_nameVARCHAR2(120)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, job_nameVARCHAR2(200)notnull, job_groupVARCHAR2(200)notnull, descriptionVARCHAR2(250), next_fire_timeNUMBER(13), prev_fire_timeNUMBER(13), priorityINTEGER, trigger_stateVARCHAR2(16)notnull, trigger_typeVARCHAR2(8)notnull, start_timeNUMBER(13)notnull, end_timeNUMBER(13), calendar_nameVARCHAR2(200), misfire_instrNUMBER(2), job_dataBLOB ); altertableQRTZ_TRIGGERS addconstraintPK_QRTZ_TRIGGERSprimarykey(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); createtableQRTZ_SIMPLE_TRIGGERS ( sched_nameVARCHAR2(120)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, repeat_countNUMBER(7)notnull, repeat_intervalNUMBER(12)notnull, times_triggeredNUMBER(10)notnull ); altertableQRTZ_SIMPLE_TRIGGERS addconstraintPK_QRTZ_SIMPLE_TRIGGERSprimarykey(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); createtableQRTZ_SIMPROP_TRIGGERS ( sched_nameVARCHAR2(120)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, str_prop_1VARCHAR2(512), str_prop_2VARCHAR2(512), str_prop_3VARCHAR2(512), int_prop_1INTEGER, int_prop_2INTEGER, long_prop_1NUMBER, long_prop_2NUMBER, dec_prop_1NUMBER(13,4), dec_prop_2NUMBER(13,4), bool_prop_1VARCHAR2(1), bool_prop_2VARCHAR2(1) ); altertableQRTZ_SIMPROP_TRIGGERS addconstraintPK_QRTZ_SIMPROP_TRIGGERSprimarykey(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); createtableQRTZ_BLOB_TRIGGERS ( sched_nameVARCHAR2(120)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, blob_dataBLOB ); altertableQRTZ_BLOB_TRIGGERS addconstraintPK_QRTZ_BLOB_TRIGGERSprimarykey(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); createtableQRTZ_CRON_TRIGGERS ( sched_nameVARCHAR2(120)notnull, trigger_nameVARCHAR2(200)notnull, trigger_groupVARCHAR2(200)notnull, cron_expressionVARCHAR2(200)notnull, time_zone_idVARCHAR2(80) ); altertableQRTZ_CRON_TRIGGERS addconstraintPK_QRTZ_CRON_TRIGGERSprimarykey(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); deletefromQRTZ_JOB_DETAILS; deletefromQRTZ_CRON_TRIGGERS; deletefromQRTZ_BLOB_TRIGGERS; deletefromQRTZ_CALENDARS; deletefromQRTZ_FIRED_TRIGGERS; deletefromQRTZ_LOCKS; deletefromQRTZ_PAUSED_TRIGGER_GRPS; deletefromQRTZ_SCHEDULER_STATE; deletefromQRTZ_SIMPLE_TRIGGERS; deletefromQRTZ_SIMPROP_TRIGGERS; deletefromQRTZ_TRIGGERS;
Maven
我这里后台使用的是Springboot2.1
org.springframework.boot spring-boot-starter-quartz
application.yml
quartz: #quartz相关属性配置 properties: org: quartz: scheduler: instanceName:clusteredScheduler#调度器的实例名 instanceId:AUTO#调度器编号自动生成 jobStore: class:org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix:qrtz_#数据库表名前缀 isClustered:true#开启分布式部署 clusterCheckinInterval:10000#分布式节点有效性检查时间间隔,单位:秒 useProperties:false threadPool: class:org.quartz.simpl.SimpleThreadPool#自带的线程池实现类 threadCount:10#开启10个线程 threadPriority:5#工作者线程的优先级 threadsInheritContextClassLoaderOfInitializingThread:true #数据库方式 job-store-type:jdbc
Bean
importorg.quartz.JobDataMap;
importjava.util.Date;
/**
*@program:QuartzBean
*@description:
*@author:Yuwl
*@create:2020-06-0218:36
**/
publicclassQuartzBean{
/**任务id*/
privateStringid;
/**任务名称*/
privateStringjobName;
/**任务组*/
privateStringjobGroup;
/**任务执行类*/
privateStringjobClass;
/**任务状态启动还是暂停*/
privateIntegerstatus;
/**
*任务开始时间
*/
privateDatestartTime;
/**
*任务循环间隔-单位:分钟
*/
privateIntegerinterval;
/**
*任务结束时间
*/
privateDateendTime;
/**任务运行时间表达式*/
privateStringcronExpression;
privateJobDataMapjobDataMap;
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicStringgetJobName(){
returnjobName;
}
publicvoidsetJobName(StringjobName){
this.jobName=jobName;
}
publicStringgetJobClass(){
returnjobClass;
}
publicvoidsetJobClass(StringjobClass){
this.jobClass=jobClass;
}
publicIntegergetStatus(){
returnstatus;
}
publicvoidsetStatus(Integerstatus){
this.status=status;
}
publicStringgetCronExpression(){
returncronExpression;
}
publicvoidsetCronExpression(StringcronExpression){
this.cronExpression=cronExpression;
}
publicDategetStartTime(){
returnstartTime;
}
publicvoidsetStartTime(DatestartTime){
this.startTime=startTime;
}
publicIntegergetInterval(){
returninterval;
}
publicvoidsetInterval(Integerinterval){
this.interval=interval;
}
publicDategetEndTime(){
returnendTime;
}
publicvoidsetEndTime(DateendTime){
this.endTime=endTime;
}
publicJobDataMapgetJobDataMap(){
returnjobDataMap;
}
publicvoidsetJobDataMap(JobDataMapjobDataMap){
this.jobDataMap=jobDataMap;
}
publicStringgetJobGroup(){
returnjobGroup;
}
publicvoidsetJobGroup(StringjobGroup){
this.jobGroup=jobGroup;
}
}
Service
importcom.baomidou.mybatisplus.core.toolkit.ObjectUtils;
importcom.ruoyi.framework.quartz.QuartzBean;
importorg.quartz.*;
importorg.quartz.impl.matchers.GroupMatcher;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Service;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Set;
/**
*@program:QuartzJobService
*@description:
*@author:Yuwl
*@create:2020-07-2117:00
**/
@Service
publicclassQuartzJobService{
@Autowired
privateSchedulerscheduler;
/**
*创建定时任务Simple
*quartzBean.getInterval()==null表示单次提醒,
*否则循环提醒(quartzBean.getEndTime()!=null)
*@paramquartzBean
*/
publicvoidcreateScheduleJobSimple(QuartzBeanquartzBean)throwsException{
//获取到定时任务的执行类必须是类的绝对路径名称
//定时任务类需要是job类的具体实现QuartzJobBean是job的抽象类。
ClassjobClass=(Class)Class.forName(quartzBean.getJobClass());
//构建定时任务信息
JobDetailjobDetail=JobBuilder.newJob(jobClass)
.withIdentity(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null)
.setJobData(quartzBean.getJobDataMap())
.build();
//设置定时任务执行方式
SimpleScheduleBuildersimpleScheduleBuilder=null;
if(quartzBean.getInterval()==null){//单次
simpleScheduleBuilder=SimpleScheduleBuilder.simpleSchedule();
}else{//循环
simpleScheduleBuilder=SimpleScheduleBuilder.repeatMinutelyForever(quartzBean.getInterval());
}
//构建触发器trigger
Triggertrigger=null;
if(quartzBean.getInterval()==null){//单次
trigger=TriggerBuilder.newTrigger()
.withIdentity(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null)
.withSchedule(simpleScheduleBuilder)
.startAt(quartzBean.getStartTime())
.build();
}else{//循环
trigger=TriggerBuilder.newTrigger()
.withIdentity(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null)
.withSchedule(simpleScheduleBuilder)
.startAt(quartzBean.getStartTime())
.endAt(quartzBean.getEndTime())
.build();
}
scheduler.scheduleJob(jobDetail,trigger);
}
/**
*创建定时任务Cron
*定时任务创建之后默认启动状态
*@paramquartzBean定时任务信息类
*@throwsException
*/
publicvoidcreateScheduleJobCron(QuartzBeanquartzBean)throwsException{
//获取到定时任务的执行类必须是类的绝对路径名称
//定时任务类需要是job类的具体实现QuartzJobBean是job的抽象类。
ClassjobClass=(Class)Class.forName(quartzBean.getJobClass());
//构建定时任务信息
JobDetailjobDetail=JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName()).setJobData(quartzBean.getJobDataMap()).build();
//设置定时任务执行方式
CronScheduleBuilderscheduleBuilder=CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
//构建触发器trigger
CronTriggertrigger=TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,trigger);
}
/**
*根据任务名称暂停定时任务
*@paramjobName定时任务名称
*@paramjobGroup任务组(没有分组传值null)
*@throwsException
*/
publicvoidpauseScheduleJob(StringjobName,StringjobGroup)throwsException{
JobKeyjobKey=JobKey.jobKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
scheduler.pauseJob(jobKey);
}
/**
*根据任务名称恢复定时任务
*@paramjobName定时任务名
*@paramjobGroup任务组(没有分组传值null)
*@throwsSchedulerException
*/
publicvoidresumeScheduleJob(StringjobName,StringjobGroup)throwsException{
JobKeyjobKey=JobKey.jobKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
scheduler.resumeJob(jobKey);
}
/**
*根据任务名称立即运行一次定时任务
*@paramjobName定时任务名称
*@paramjobGroup任务组(没有分组传值null)
*@throwsSchedulerException
*/
publicvoidrunOnce(StringjobName,StringjobGroup)throwsException{
JobKeyjobKey=JobKey.jobKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
scheduler.triggerJob(jobKey);
}
/**
*更新定时任务Simple
*@paramquartzBean定时任务信息类
*@throwsSchedulerException
*/
publicvoidupdateScheduleJobSimple(QuartzBeanquartzBean)throwsException{
//获取到对应任务的触发器
TriggerKeytriggerKey=TriggerKey.triggerKey(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null);
//设置定时任务执行方式
SimpleScheduleBuildersimpleScheduleBuilder=null;
if(quartzBean.getInterval()==null){//单次
simpleScheduleBuilder=SimpleScheduleBuilder.simpleSchedule();
}else{//循环
simpleScheduleBuilder=SimpleScheduleBuilder.repeatMinutelyForever(quartzBean.getInterval());
}
//构建触发器trigger
Triggertrigger=null;
if(quartzBean.getInterval()==null){//单次
trigger=TriggerBuilder.newTrigger()
.withIdentity(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null)
.withSchedule(simpleScheduleBuilder)
.startAt(quartzBean.getStartTime())
.build();
}else{//循环
TriggerBuilder.newTrigger()
.withIdentity(quartzBean.getJobName(),ObjectUtils.isNotEmpty(quartzBean.getJobGroup())?quartzBean.getJobGroup():null)
.withSchedule(simpleScheduleBuilder)
.startAt(quartzBean.getStartTime())
.endAt(quartzBean.getEndTime())
.build();
}
//重置对应的job
scheduler.rescheduleJob(triggerKey,trigger);
}
/**
*更新定时任务Cron
*@paramquartzBean定时任务信息类
*@throwsSchedulerException
*/
publicvoidupdateScheduleJobCron(QuartzBeanquartzBean)throwsException{
//获取到对应任务的触发器
TriggerKeytriggerKey=TriggerKey.triggerKey(quartzBean.getJobName());
//设置定时任务执行方式
CronScheduleBuilderscheduleBuilder=CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
//重新构建任务的触发器trigger
CronTriggertrigger=(CronTrigger)scheduler.getTrigger(triggerKey);
trigger=trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//重置对应的job
scheduler.rescheduleJob(triggerKey,trigger);
}
/**
*根据定时任务名称从调度器当中删除定时任务
*@paramjobName定时任务名称
*@paramjobGroup任务组(没有分组传值null)
*@throwsSchedulerException
*/
publicvoiddeleteScheduleJob(StringjobName,StringjobGroup)throwsException{
JobKeyjobKey=JobKey.jobKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
scheduler.deleteJob(jobKey);
}
/**
*获取任务状态
*@paramjobName
*@paramjobGroup任务组(没有分组传值null)
*@return
*("BLOCKED","阻塞");
*("COMPLETE","完成");
*("ERROR","出错");
*("NONE","不存在");
*("NORMAL","正常");
*("PAUSED","暂停");
*/
publicStringgetScheduleJobStatus(StringjobName,StringjobGroup)throwsException{
TriggerKeytriggerKey=TriggerKey.triggerKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
Trigger.TriggerStatestate=scheduler.getTriggerState(triggerKey);
returnstate.name();
}
/**
*根据定时任务名称来判断任务是否存在
*@paramjobName定时任务名称
*@paramjobGroup任务组(没有分组传值null)
*@throwsSchedulerException
*/
publicBooleancheckExistsScheduleJob(StringjobName,StringjobGroup)throwsException{
JobKeyjobKey=JobKey.jobKey(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
returnscheduler.checkExists(jobKey);
}
/**
*根据任务組刪除定時任务
*@paramjobGroup任务组
*@throwsSchedulerException
*/
publicBooleandeleteGroupJob(StringjobGroup)throwsException{
GroupMatchermatcher=GroupMatcher.groupEquals(jobGroup);
SetjobkeySet=scheduler.getJobKeys(matcher);
ListjobkeyList=newArrayList();
jobkeyList.addAll(jobkeySet);
returnscheduler.deleteJobs(jobkeyList);
}
/**
*根据任务組批量刪除定時任务
*@paramjobkeyList
*@throwsSchedulerException
*/
publicBooleanbatchDeleteGroupJob(ListjobkeyList)throwsException{
returnscheduler.deleteJobs(jobkeyList);
}
/**
*根据任务組批量查询出jobkey
*@paramjobGroup任务组
*@throwsSchedulerException
*/
publicvoidbatchQueryGroupJob(ListjobkeyList,StringjobGroup)throwsException{
GroupMatchermatcher=GroupMatcher.groupEquals(jobGroup);
SetjobkeySet=scheduler.getJobKeys(matcher);
jobkeyList.addAll(jobkeySet);
}
}
Job
packagecom.quartz.demo.job
importorg.quartz.JobDataMap;
importorg.quartz.JobExecutionContext;
importorg.quartz.JobExecutionException;
importorg.quartz.JobKey;
importorg.springframework.scheduling.quartz.QuartzJobBean;
importorg.springframework.stereotype.Component;
importjava.util.Date;
/**
*@program:job
*@description:
*@author:Yuwl
*@create:2020-06-0218:07
**/
@Component
publicclassMyTaskextendsQuartzJobBean{
@Override
protectedvoidexecuteInternal(JobExecutionContextcontext)throwsJobExecutionException{
JobKeyjobKey=context.getJobDetail().getKey();
JobDataMapmap=context.getJobDetail().getJobDataMap();
StringuserId=map.getString("userId");
System.out.println("SimpleJobsays:"+jobKey+",userId:"+userId+"executingat"+newDate());
}
}
Controller
importcom.baomidou.mybatisplus.core.toolkit.ObjectUtils;
importcom.ruoyi.common.utils.DateUtils;
importcom.ruoyi.framework.quartz.QuartzBean;
importcom.ruoyi.framework.quartz.service.QuartzJobService;
importorg.quartz.JobDataMap;
importorg.quartz.SchedulerException;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.*;
importjava.text.ParseException;
importjava.util.Date;
/**
*@program:JobController
*@description:
*@author:Yuwl
*@create:2020-07-2117:08
**/
@RestController
@RequestMapping("/api/quartz/")
publicclassJobController{
@Autowired
privateQuartzJobServicequartzJobService;
//创建&启动
@GetMapping("startSimpleJob")
publicStringstartSimpleJob()throwsSchedulerException,ClassNotFoundException,ParseException{
QuartzBeanquartzBean=newQuartzBean();
quartzBean.setJobClass("com.quartz.demo.job.MyTask");
quartzBean.setJobName("job1");
JobDataMapmap=newJobDataMap();
map.put("userId","123456");
quartzBean.setJobDataMap(map);
Datenow=newDate();
quartzBean.setStartTime(DateUtils.addSeconds(now,10));
quartzBean.setInterval(10);
quartzBean.setEndTime(DateUtils.addMinutes(now,1));
try{
quartzJobService.createScheduleJobSimple(quartzBean);
}catch(Exceptione){
e.printStackTrace();
}
return"startJobSuccess!";
}
/**
*创建cronJob
*@paramquartzBean
*@return
*/
@RequestMapping("/createCronJob")
@ResponseBody
publicStringcreateJob(QuartzBeanquartzBean){
try{
//进行测试所以写死
quartzBean.setJobClass("com.quartz.demo.job.MyTask");
quartzBean.setJobName("job1");
quartzBean.setCronExpression("*/5****?");
quartzJobService.createScheduleJobCron(quartzBean);
}catch(Exceptione){
return"创建失败";
}
return"创建成功";
}
/**
*暂停job
*@return
*/
@RequestMapping(value={"/pauseJob/{jobName}","/pauseJob/{jobName}/{jobGroup}"})
@ResponseBody
publicStringpauseJob(@PathVariable("jobName")StringjobName,@PathVariable(required=false)StringjobGroup){
try{
quartzJobService.pauseScheduleJob(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
}catch(Exceptione){
return"暂停失败";
}
return"暂停成功";
}
@RequestMapping(value={"/resume/{jobName}","/resume/{jobName}/{jobGroup}"})
@ResponseBody
publicStringresume(@PathVariable("jobName")StringjobName,@PathVariable(required=false)StringjobGroup){
try{
quartzJobService.resumeScheduleJob(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
}catch(Exceptione){
return"启动失败";
}
return"启动成功";
}
@RequestMapping(value={"/delete/{jobName}","/delete/{jobName}/{jobGroup}"})
publicStringdelete(@PathVariable("jobName")StringjobName,@PathVariable(required=false)StringjobGroup){
try{
quartzJobService.deleteScheduleJob(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
}catch(Exceptione){
return"删除失败";
}
return"删除成功";
}
@RequestMapping(value={"/check/{jobName}","/check/{jobName}/{jobGroup}"})
publicStringcheck(@PathVariable("jobName")StringjobName,@PathVariable(required=false)StringjobGroup){
try{
if(quartzJobService.checkExistsScheduleJob(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null)){
return"存在定时任务:"+jobName;
}else{
return"不存在定时任务:"+jobName;
}
}catch(Exceptione){
return"查询任务失败";
}
}
@RequestMapping(value={"/status/{jobName}","/status/{jobName}/{jobGroup}"})
@ResponseBody
publicStringstatus(@PathVariable("jobName")StringjobName,@PathVariable(required=false)StringjobGroup){
try{
returnquartzJobService.getScheduleJobStatus(jobName,ObjectUtils.isNotEmpty(jobGroup)?jobGroup:null);
}catch(Exceptione){
return"获取状态失败";
}
//return"获取状态成功";
}
}
测试
http://localhost:8080/api/quartz/startSimpleJob
到此这篇关于Springboot2.x+Quartz分布式集群的实现的文章就介绍到这了,更多相关Springboot2.xQuartz分布式集群内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!