quartz动态定时任务


前言

基于springBoot + quartz 开发
springboot 2.1.2.RELEASE
jdk 1.8

主要用于动态定时任务操作,例如新增、修改、暂停、关闭、删除


一、项目相关依赖

1.maven依赖

 <!--quartz-->
 <dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.数据库文件

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;

二、添加相关配置

1.application.yml添加quartz配置

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

2.增加ScheduleConfig文件

/**
 * 定时任务配置类
 *
 * @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();
    }

}

3.具体代码

service层
/**
 * @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);

}
serviceimpl层
/**
 * @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();
        }
    }
}

dto文件
/**
 * @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;

}
action层
/**
 * @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;
    }
}
MQRetryJob文件
/**
 * @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()));
    }

}
增加传参及动态微服务调用 2022-09-07
ScheduleService类
/**
     * 添加定时任务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;
    }
    
QuartzJob类
/**
 * @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);
    }

}
效果图

在这里插入图片描述
在这里插入图片描述


  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。 Quartz的优势: 1、Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。 2、Quartz是非常灵活的,它让您能够以最“自然”的方式来编写您的项目的代码,实现您所期望的行为 3、Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。 4、Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。 5、可以通过Quartz,封装成自己的分布式任务调度,实现强大的功能,成为自己的产品。6、有很多的互联网公司也都在使用Quartz。比如美团 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。   课程说明:在我们的日常开发中,各种大型系统的开发少不了任务调度,简单的单机任务调度已经满足不了我们的系统需求,复杂的任务会让程序猿头疼, 所以急需一套专门的框架帮助我们去管理定时任务,并且可以在多台机器去执行我们的任务,还要可以管理我们的分布式定时任务。本课程从Quartz框架讲起,由浅到深,从使用到结构分析,再到源码分析,深入解析QuartzSpring+Quartz,并且会讲解相关原理, 让大家充分的理解这个框架和框架的设计思想。由于互联网的复杂性,为了满足我们特定的需求,需要对Spring+Quartz进行二次开发,整个二次开发过程都会进行讲解。Spring被用在了越来越多的项目中, Quartz也被公认为是比较好用的定时器设置工具,学完这个课程后,不仅仅可以熟练掌握分布式定时任务,还可以深入理解大型框架的设计思想。
### 回答1: Springboot定时任务可以通过配置文件(application.properties 或 application.yml)来管理,具体的代码如下:spring.quartz.properties.org.quartz.scheduler.instanceName=MyScheduler spring.quartz.properties.org.quartz.threadPool.threadCount=3 spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate spring.quartz.properties.org.quartz.jobStore.useProperties=false spring.quartz.properties.org.quartz.jobStore.dataSource=myDS spring.quartz.properties.org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver spring.quartz.properties.org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/quartz spring.quartz.properties.org.quartz.dataSource.myDS.user=root spring.quartz.properties.org.quartz.dataSource.myDS.password=123456 spring.quartz.properties.org.quartz.dataSource.myDS.maxConnections=5 ### 回答2: Spring Boot定时任务可以通过在配置文件中配置以下代码来实现: 首先,需要确保在pom.xml文件中添加依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> ``` 然后,在application.properties或application.yml配置文件中进行定时任务的配置,例如: 配置文件application.properties: ```properties # 开启定时任务 spring.task.scheduling.enabled=true # 配置定时任务执行频率,每隔5秒执行一次 spring.task.scheduling.fixed-rate=5000 # 配置定时任务执行时间,每天上午9点执行 spring.task.scheduling.cron=0 0 9 * * ? # 执行定时任务的线程池大小 spring.task.scheduling.pool.size=10 ``` 配置文件application.yml: ```yaml spring: task: scheduling: enabled: true fixed-rate: 5000 cron: 0 0 9 * * ? scheduling: pool: size: 10 ``` 以上配置代码中,`spring.task.scheduling.enabled`参数用来开启定时任务,`spring.task.scheduling.fixed-rate`参数用来配置定时任务的执行频率(以毫秒为单位),`spring.task.scheduling.cron`参数用来配置定时任务的执行时间(使用Cron表达式),`spring.task.scheduling.pool.size`参数用来配置执行定时任务的线程池大小。 通过以上的配置代码,就可以实现Spring Boot定时任务配置。 ### 回答3: Spring Boot 定时任务配置文件可以使用 @EnableScheduling 注解开启定时任务功能,并在需要定时执行的方法上添加 @Scheduled 注解进行配置。 首先,在 Spring Boot 的配置类上使用 @EnableScheduling 注解开启定时任务功能,例如: ```java import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.context.annotation.Configuration; @Configuration @EnableScheduling public class AppConfig { } ``` 然后,在需要执行定时任务的方法上使用 @Scheduled 注解进行配置,指定定时任务的执行时间、频率等,例如: ```java import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class MyScheduledTask { @Scheduled(fixedDelay = 1000) // 每隔1秒执行一次 public void task1() { // 定时任务的逻辑代码 } @Scheduled(cron = "0 0 12 * * ?") // 每天12点执行 public void task2() { // 定时任务的逻辑代码 } } ``` 可以根据实际需要使用 @Scheduled 注解的不同属性进行定时任务的配置,常用的属性包括 fixedDelay(固定延时)、fixedRate(固定频率)、initialDelay(初始延时)、cron(Cron 表达式)等。 最后,程序启动后,定时任务就会按照配置的时间和频率自动执行。注意,定时任务的方法需要被 Spring 容器管理,所以要加上 @Component 等注解使其成为 Spring Bean。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值