基于springBoot + quartz 开发
springboot 2.1.2.RELEASE
jdk 1.8
主要用于动态定时任务操作,例如新增、修改、暂停、关闭、删除
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_blob_triggers`;
CREATE TABLE `qrtz_blob_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`BLOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `SCHED_NAME`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_calendars
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_calendars`;
CREATE TABLE `qrtz_calendars` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`CALENDAR_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`CALENDAR` blob NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_cron_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_cron_triggers`;
CREATE TABLE `qrtz_cron_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`CRON_EXPRESSION` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TIME_ZONE_ID` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_fired_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_fired_triggers`;
CREATE TABLE `qrtz_fired_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`ENTRY_ID` varchar(95) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`INSTANCE_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`FIRED_TIME` bigint(13) NOT NULL,
`SCHED_TIME` bigint(13) NOT NULL,
`PRIORITY` int(11) NOT NULL,
`STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `ENTRY_ID`) USING BTREE,
INDEX `IDX_QRTZ_FT_TRIG_INST_NAME`(`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE,
INDEX `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME`, `INSTANCE_NAME`, `REQUESTS_RECOVERY`) USING BTREE,
INDEX `IDX_QRTZ_FT_J_G`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_FT_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_FT_T_G`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_FT_TG`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_job_details
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_job_details`;
CREATE TABLE `qrtz_job_details` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`JOB_CLASS_NAME` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`IS_DURABLE` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`IS_UPDATE_DATA` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_J_REQ_RECOVERY`(`SCHED_NAME`, `REQUESTS_RECOVERY`) USING BTREE,
INDEX `IDX_QRTZ_J_GRP`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_locks
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_locks`;
CREATE TABLE `qrtz_locks` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`LOCK_NAME` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `LOCK_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_paused_trigger_grps
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;
CREATE TABLE `qrtz_paused_trigger_grps` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_scheduler_state
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_scheduler_state`;
CREATE TABLE `qrtz_scheduler_state` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`INSTANCE_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`LAST_CHECKIN_TIME` bigint(13) NOT NULL,
`CHECKIN_INTERVAL` bigint(13) NOT NULL,
PRIMARY KEY (`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_simple_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simple_triggers`;
CREATE TABLE `qrtz_simple_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci 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`) USING BTREE,
CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_simprop_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_simprop_triggers`;
CREATE TABLE `qrtz_simprop_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`STR_PROP_1` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`STR_PROP_2` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`STR_PROP_3` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`INT_PROP_1` int(11) NULL DEFAULT NULL,
`INT_PROP_2` int(11) NULL DEFAULT NULL,
`LONG_PROP_1` bigint(20) NULL DEFAULT NULL,
`LONG_PROP_2` bigint(20) NULL DEFAULT NULL,
`DEC_PROP_1` decimal(13, 4) NULL DEFAULT NULL,
`DEC_PROP_2` decimal(13, 4) NULL DEFAULT NULL,
`BOOL_PROP_1` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`BOOL_PROP_2` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for qrtz_triggers
-- ----------------------------
DROP TABLE IF EXISTS `qrtz_triggers`;
CREATE TABLE `qrtz_triggers` (
`SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`NEXT_FIRE_TIME` bigint(13) NULL DEFAULT NULL,
`PREV_FIRE_TIME` bigint(13) NULL DEFAULT NULL,
`PRIORITY` int(11) NULL DEFAULT NULL,
`TRIGGER_STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`TRIGGER_TYPE` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`START_TIME` bigint(13) NOT NULL,
`END_TIME` bigint(13) NULL DEFAULT NULL,
`CALENDAR_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`MISFIRE_INSTR` smallint(2) NULL DEFAULT NULL,
`JOB_DATA` blob NULL,
PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_J`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_C`(`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE,
INDEX `IDX_QRTZ_T_G`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE,
INDEX `IDX_QRTZ_T_STATE`(`SCHED_NAME`, `TRIGGER_STATE`) USING BTREE,
INDEX `IDX_QRTZ_T_N_STATE`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
INDEX `IDX_QRTZ_T_N_G_STATE`(`SCHED_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
INDEX `IDX_QRTZ_T_NEXT_FIRE_TIME`(`SCHED_NAME`, `NEXT_FIRE_TIME`) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST`(`SCHED_NAME`, `TRIGGER_STATE`, `NEXT_FIRE_TIME`) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_STATE`) USING BTREE,
INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE,
CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
server:
port: 8090
spring:
datasource:
#第一数据库
primary:
#MYSQL数据库
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.1.1:3306/my_quartz?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
#数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行,如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中。
removeAbandoned: true
#超时时间,秒
removeAbandonedTimeout: 1800
#abanded连接时输出错误日志,这样出现连接泄露时可以通过错误日志定位忘记关闭连接的位置
logAbandoned: true
#配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
druid:
initial-size: 5 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
#有多个数据源时,配置公用监控数据
use-global-data-source-stat: true
web-stat-filter:
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
stat-view-servlet: #访问监控网页的登录用户名和密码
login-username: druid
login-password: druid
quartz:
job-store-type: jdbc #将任务保存到数据库
wait-for-jobs-to-complete-on-shutdown: true #程序结束时会等待quartz相关内容结束
overwrite-existing-jobs: true #启动时更新已存在的job
jdbc:
initialize-schema: never
properties:
org:
quartz:
scheduler:
instanceName: scheduler #实例名
instanceId: AUTO #实例编号自动生成
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX #数据保存方式为数据库持久化
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #数据库代理类
tablePrefix: QRTZ_ #数据表的前缀
isClustered: false #是否以集群方式运行
clusterCheckinInterval: 10000 #调度实例失效的检查时间间隔,单位毫秒
useProperties: true #JobDataMaps是否都为String类型
misfireThreshold: 60000 #最大能忍受的触发超时时间
threadPool:
class: org.quartz.simpl.SimpleThreadPool #连接池实现类
threadCount: 10 #线程数量
threadPriority: 5 #线程优先级
threadsInheritContextClassLoaderOfInitializingThread: true #配置是否启动自动加载数据库内的定时任务,默认true
/**
* 定时任务配置类
*
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 09:57:41
*/
@Configuration
public class ScheduleConfig {
@Resource
private SchedulerFactoryBean schedulerFactoryBean;
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean.getScheduler();
}
}
/**
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 10:08:08
*/
public interface IScheduleService {
/**
* 添加定时任务Job
*
*/
void addSchedule(ScheduleInfoDto dto);
/**
* 暂停定时任务
*
* @param jobName
* @param jobGroup
*/
void pauseSchedule(String jobName, String jobGroup);
/**
* 恢复定时任务
*
* @param jobName
* @param jobGroup
*/
void resumeSchedule(String jobName, String jobGroup);
/**
* 更新定时任务
*
*/
void updateSchedule(ScheduleInfoDto dto);
/**
* 删除定时任务
*
* @param jobName
* @param jobGroup
*/
void deleteSchedule(String jobName, String jobGroup);
}
/**
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 10:17:16
*/
@Service
public class ScheduleService implements IScheduleService {
@Resource
private Scheduler scheduler;
/**
* 添加定时任务Job
*/
@Override
public void addSchedule(ScheduleInfoDto dto) {
try {
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(dto.getJobClassName()))
.withIdentity(dto.getJobName(), dto.getJobGroup())
.storeDurably()
.build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(dto.getTriggerName(), dto.getTriggerGroup())
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(dto.getCronExpression()).withMisfireHandlingInstructionDoNothing())
.build();
scheduler.scheduleJob(jobDetail, cronTrigger);
} catch (SchedulerException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 暂停定时任务
*
* @param jobName
* @param jobGroup
*/
@Override
public void pauseSchedule(String jobName, String jobGroup) {
try {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复定时任务
*
* @param jobName
* @param jobGroup
*/
@Override
public void resumeSchedule(String jobName, String jobGroup) {
try {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 更新定时任务
*/
@SneakyThrows
@Override
public void updateSchedule(ScheduleInfoDto dto) {
JobKey jobKey = new JobKey(dto.getJobName(), dto.getJobGroup());
//检查任务key是否存在
if (scheduler.checkExists(jobKey)) {
deleteSchedule(dto.getJobName(), dto.getJobGroup());
}
//按新的trigger重新设置job执行,重启触发器
addSchedule(dto);
}
/**
* 删除定时任务
*
* @param jobName
* @param jobGroup
*/
@Override
public void deleteSchedule(String jobName, String jobGroup) {
try {
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
/**
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 14:12:14
*/
@Data
public class ScheduleInfoDto implements Serializable {
@ApiModelProperty(value = "服务名称")
private String serveName;
@ApiModelProperty(value = "接口地址")
private String interfaceAddress;
@ApiModelProperty(value = "任务描述")
private String descName;
@ApiModelProperty(value = "任务名称")
private String jobName;
@ApiModelProperty(value = "任务组")
private String jobGroup;
@ApiModelProperty(value = "任务路径")
private String jobClassName;
@ApiModelProperty(value = "调度器名称")
private String triggerName;
@ApiModelProperty(value = "调度器组")
private String triggerGroup;
@ApiModelProperty(value = "表达式")
private String cronExpression;
@ApiModelProperty(value = "附加参数,会传给定时任务接口")
private String extras;
}
/**
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 10:34:56
*/
@RestController
@RequestMapping(value = "/quartz")
@Api(tags = "Quartz定时任务管理")
public class QuartzAction {
@Resource
private IScheduleService scheduleService;
@PostMapping(value = "/test")
public RetType test(){
RetType retType = new RetType();
ScheduleInfoDto dto = new ScheduleInfoDto();
scheduleInfoDto.setJobName("mqRetryJob");
scheduleInfoDto.setJobGroup("mqRetryJobGroup");
scheduleInfoDto.setJobClassName("com.safeneeds.schedulemana.job.MQRetryJob");
scheduleInfoDto.setTriggerName("mqRetryJobTrigger");
scheduleInfoDto.setTriggerGroup("mqRetryJobTriggerGroup");
scheduleService.addSchedule(dto);
retType.doSuccess();
return retType;
}
}
/**
* @author czw
* @version 1.0
* @describe:
* @date 2022/06/28 14:44:58
*/
@Slf4j
public class MQRetryJob implements Job {
//这里有个坑,必须使用该注解,否则无法注入bean
@Resource
private IMqFeignService mqFeignService;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
mqFeignService.handleRetry();
log.info("--------------执行mq重试处理,执行时间:{}:", DateUtil.formatDateTime(new Date()));
}
}
/**
* 添加定时任务Job
*/
@SneakyThrows
@Override
public RetType addSchedule(ScheduleInfoDto dto) {
RetType retType = new RetType();
JobKey jobKey = new JobKey(dto.getJobName(), dto.getJobGroup());
//检查任务key是否存在
if (scheduler.checkExists(jobKey)) {
retType.doError("该任务名称及任务组已存在!");
return retType;
}
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("serveName", dto.getServeName());
jobDataMap.put("interfaceAddress", dto.getInterfaceAddress());
if (ObjectUtil.isNotEmpty(dto.getExtras())) {
jobDataMap.put("extras", dto.getExtras());
}
if (StrUtil.isEmpty(dto.getJobClassName())) {
dto.setJobClassName("com.xxxx.schedulemana.job.QuartzJob");
}
if (StrUtil.isEmpty(dto.getTriggerName())) {
dto.setTriggerName("jobTrigger" + IdUtil.fastSimpleUUID());
}
if (StrUtil.isEmpty(dto.getTriggerGroup())) {
dto.setTriggerGroup("jobTriggerGroup" + IdUtil.fastSimpleUUID());
}
try {
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(dto.getJobClassName()))
.withIdentity(dto.getJobName(), dto.getJobGroup())
.usingJobData(jobDataMap)
.withDescription(dto.getDescName())
.storeDurably()
.build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(dto.getTriggerName(), dto.getTriggerGroup())
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(dto.getCronExpression()))
.build();
scheduler.scheduleJob(jobDetail, cronTrigger);
if(dto.getStatus().equals(QuartzConst.STATUS_2)){
pauseSchedule(dto);
}
retType.doSuccess();
} catch (SchedulerException | ClassNotFoundException e) {
e.printStackTrace();
retType.doError(e.getMessage());
}
return retType;
}
/**
* 执行一次
* @Auther: czw
* @Description:
* @Date: 2022/7/1 14:57
* @Version: 1.0
*/
@Override
public RetType executeOnce(String jobName, String jobGroup) {
RetType retType = new RetType();
if (StrUtil.isEmpty(jobName) || StrUtil.isEmpty(jobGroup)) {
retType.doError("任务名称或任务组不能为空!");
return retType;
}
try {
scheduler.triggerJob(JobKey.jobKey(jobName, jobGroup));
retType.doSuccess();
} catch (SchedulerException e) {
e.printStackTrace();
}
return retType;
}
/**
* @author czw
* @version 1.0
* @describe: 通用定时任务处理类
* @date 2022/06/30 11:55:37
*/
@Slf4j
public class QuartzJob implements Job {
@Resource
private RestTemplate restTemplate;
@Resource
private IQuartzLogDao quartzLogDao;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();
RetType retType;
String url = "http://" + dataMap.getString("serveName") + dataMap.getString("interfaceAddress");
if(dataMap.containsKey("extras")){
retType = restTemplate.postForObject(url, JSON.parseObject(dataMap.getString("extras")), RetType.class);
}else{
retType = restTemplate.postForObject(url,new JSONObject(),RetType.class);
}
//记录定时器日志
QuartzLog quartzLog = new QuartzLog();
JobKey key = jobExecutionContext.getJobDetail().getKey();
quartzLog.setJobName(key.getName());
quartzLog.setJobGroup(key.getGroup());
quartzLog.setServiceName(dataMap.getString("serveName"));
quartzLog.setMethodName(dataMap.getString("interfaceAddress"));
quartzLog.setExecuteTime(new Date());
quartzLog.setStatus(retType.getErrCode());
quartzLog.setTaskDesc(jobExecutionContext.getJobDetail().getDescription());
quartzLog.setFailReason(retType.getErrMsg());
quartzLogDao.saveQuartzLog(quartzLog);
}
}