SpringBoot整合Quartz任务,java对任务创建、删除、修改、查询

SpringBoot整合Quartz定时任务

  • 1、定时任务相关概念
  • 2、SpringBoot集成Quartz
    • 2.1、Quartz相关表
    • 2.2、pom.xml
    • 2.3、application.yml
    • 2.4、java对任务增删改查
      • 2.4.1、common相关配置类
      • 2.4.2、pojo类
      • 2.4.3、task类
      • 2.4.4、Controller类
  • 3、一些理解
    • 3.1、Quartz的集群原理以及配置?

1、定时任务相关概念

SpringBoot中的@Schedule定时任务并不支持动态管理定时任务,且项目重启后,任务相当于重新创,实际重新创建对任务影响也不大。

而Quartz则支持对定时任务的创建,删除,修改,查询,很灵活的管理了定时任务,Quartz任务也支持分布式部署和任务信息持久化,重启项目后任务仍然存在。

2、SpringBoot集成Quartz

下面整合的代码,直接复制在企业级项目中使用即可,完全符合企业项目的使用,很灵活,很动态。

2.1、Quartz相关表

Quartz自定11张表,直接导入即可

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;

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;

2.2、pom.xml

    <dependencies>
        <!--引入web starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--引入lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
    </dependencies>

2.3、application.yml

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/quartz_test?useUnicode=true&autoReconnect=true&failOverReadOnly=false&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL
  quartz:
    job-store-type: jdbc #数据库方式
    jdbc:
      initialize-schema: never #不初始化表结构
    properties:
      org:
        quartz:
          scheduler:
            instanceId: AUTO #默认主机名和时间戳生成实例ID,可以是任何字符串,但对于所有调度程序来说,必须是唯一的 对应qrtz_scheduler_state INSTANCE_NAME字段
            #instanceName: clusteredScheduler #quartzScheduler
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore # springboot>2.5.6后使用这个
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #仅为数据库制作了特定于数据库的代理
            useProperties: false #以指示JDBCJobStore将JobDataMaps中的所有值都作为字符串,因此可以作为名称 - 值对存储而不是在BLOB列中以其序列化形式存储更多复杂的对象。从长远来看,这是更安全的,因为您避免了将非String类序列化为BLOB的类版本问题。
            tablePrefix: qrtz_  #数据库表前缀
            misfireThreshold: 60000 #在被认为“失火”之前,调度程序将“容忍”一个Triggers将其下一个启动时间通过的毫秒数。默认值(如果您在配置中未输入此属性)为60000(60秒)。
            clusterCheckinInterval: 5000 #设置此实例“检入”*与群集的其他实例的频率(以毫秒为单位)。影响检测失败实例的速度。
            isClustered: true #打开群集功能
          threadPool: #连接池
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

2.4、java对任务增删改查

SpringBoot整合Quartz任务,java对任务创建、删除、修改、查询_第1张图片

2.4.1、common相关配置类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
@Service
public class InitHandler {

    @Autowired
    private TaskInitHandler taskInitHandler;

    /**
     * 系统初始化任务入口。
     * 如果系统在启动时需要添加一些定时任务,把业务逻辑写到taskInitHandler.init()方法里即可
     */
    @PostConstruct
    public void init() {
        taskInitHandler.init();
    }
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TaskInitHandler {

    public void init() {
      log.info("初始化定时任务业务逻辑......");
    }
}
import cn.yx.zg.pojo.QuartzBean;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 该类提供对quartz任务的创建、删除、查询、修改
 */
@Service
public class QuartzJobService {

    @Resource
    private Scheduler scheduler;

    /**
     * 查询定时任务列表
     *
     * @return
     */
    public List<QuartzBean> getScheduleJobList() {
        List<QuartzBean> list = new ArrayList<>();
        try {
            for (String groupJob : scheduler.getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))) {
                    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                    for (Trigger trigger : triggers) {
                        QuartzBean quartzBean = new QuartzBean();
                        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                        String cronExpression = "";
                        if (trigger instanceof CronTrigger) {
                            CronTrigger cronTrigger = (CronTrigger) trigger;
                            cronExpression = cronTrigger.getCronExpression();
                            quartzBean.setCronExpression(cronExpression);
                        }
                        quartzBean.setStartTime(trigger.getStartTime());
                        quartzBean.setEndTime(trigger.getEndTime());
                        quartzBean.setJobName(jobKey.getName());
                        quartzBean.setJobGroup(jobKey.getGroup());
                        quartzBean.setJobDescription(jobDetail.getDescription());
                        quartzBean.setJobStatus(triggerState.name());
                        quartzBean.setJobClass(jobDetail.getJobClass().toGenericString());
                        quartzBean.setJobDataMap(jobDetail.getJobDataMap());
                        list.add(quartzBean);
                    }
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 创建简单调度任务
     *
     * @param quartzBean
     * @throws Exception
     */
    public void createScheduleSimpleJob(QuartzBean quartzBean) throws Exception {
        Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
        //job
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                .setJobData(quartzBean.getJobDataMap())
                .withDescription(quartzBean.getJobDescription())
                .build();
        //trigger
        Trigger trigger = null;
        //单次还是循环
        if (quartzBean.getInterval() == null) {
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionNextWithExistingCount())
                    .startAt(quartzBean.getStartTime())
                    .build();
        } else {
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(quartzBean.getInterval())
                            .withMisfireHandlingInstructionNextWithExistingCount())
                    .startAt(quartzBean.getStartTime())
                    .endAt(quartzBean.getEndTime())
                    .build();
        }
        scheduler.scheduleJob(jobDetail, trigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    /**
     * 创建cron调度任务
     *
     * @param quartzBean
     * @throws Exception
     */
    public void createScheduleCronJob(QuartzBean quartzBean) throws Exception {
        Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
        // job
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                .setJobData(quartzBean.getJobDataMap())
                .withDescription(quartzBean.getJobDescription())
                .build();
        // trigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                .withSchedule(CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression()))
                .build();
        scheduler.scheduleJob(jobDetail, trigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

    /**
     * 暂停任务
     *
     * @param jobName
     * @param jobGroup
     * @throws Exception
     */
    public void pauseScheduleJob(String jobName, String jobGroup) throws Exception {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.pauseJob(jobKey);
    }

    /**
     * 立即执行任务
     *
     * @param jobName
     * @param jobGroup
     * @throws Exception
     */
    public void runJob(String jobName, String jobGroup) throws Exception {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.triggerJob(jobKey);
    }

    /**
     * 更新简单任务
     *
     * @param quartzBean
     * @throws Exception
     */
    public void updateScheduleSimpleJob(QuartzBean quartzBean) throws Exception {
        //原任务触发器
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName(), quartzBean.getJobGroup());
        //trigger
        Trigger trigger = null;
        //单次还是循环
        if (quartzBean.getInterval() == null) {
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionNextWithExistingCount())
                    .startAt(quartzBean.getStartTime())
                    .build();
        } else {
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzBean.getJobName(), quartzBean.getJobGroup())
                    .withSchedule(SimpleScheduleBuilder.repeatMinutelyForever(quartzBean.getInterval()).withMisfireHandlingInstructionNextWithExistingCount())
                    .startAt(quartzBean.getStartTime())
                    .endAt(quartzBean.getEndTime())
                    .build();
        }
        //重置对应的job
        scheduler.rescheduleJob(triggerKey, trigger);
        //用该方法一样可以修改定时任务
        //scheduler.scheduleJob(jobDetail, trigger, true);
    }

    /**
     * 更新定时任务Cron
     *
     * @param quartzBean 定时任务信息类
     * @throws SchedulerException
     */
    public void updateScheduleCronJob(QuartzBean quartzBean) throws Exception {
        //原任务触发器
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName());
        // trigger
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(quartzBean.getJobName())
                .withSchedule(CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression()))
                .build();
        //重置对应的job
        scheduler.rescheduleJob(triggerKey, trigger);
    }

    /**
     * 删除定时任务
     *
     * @param jobName
     * @param jobGroup
     * @throws Exception
     */
    public void deleteScheduleJob(String jobName, String jobGroup) throws Exception {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.deleteJob(jobKey);
    }

    /**
     * 获取任务状态
     * (" BLOCKED ", " 阻塞 ");
     * ("COMPLETE", "完成");
     * ("ERROR", "出错");
     * ("NONE", "不存在");
     * ("NORMAL", "正常");
     * ("PAUSED", "暂停");
     */
    public String getScheduleJobStatus(String jobName, String jobGroup) throws Exception {
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        Trigger.TriggerState state = scheduler.getTriggerState(triggerKey);
        return state.name();
    }

    /**
     * 检查任务是否存在
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    public Boolean checkExistsScheduleJob(String jobName, String jobGroup) throws Exception {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        return scheduler.checkExists(jobKey);
    }
}

2.4.2、pojo类

import lombok.Data;
import org.quartz.JobDataMap;

import java.util.Date;

@Data
public class QuartzBean {

    private String id;

    private String jobName;

    private String jobGroup;

    private String jobDescription;

    private String jobClass;

    private String jobStatus;
    /**
     * 设置表示指定时间后任务开始执行
     * 一般都是设置当前时间,表示立即执行
     */
    private Date startTime;
    /**
     * 为null表示任务执行一次
     * 为数字n表示每隔n秒后执行一次
     */
    private Integer interval;
    /**
     * 表示在指定时间后任务结束
     * 如果不设置,表示任务不会结束,
     * 一般我们都会默认为null
     */
    private Date endTime;

    private String cronExpression;

    private JobDataMap jobDataMap;
}

2.4.3、task类

import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;

import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class MyTask implements Job {
    @Override
    public void execute(JobExecutionContext context) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("springboot-quartz-cluster-a" + ">>" + sdf.format(new Date()) + ":" + context.getJobDetail().getKey() + "执行中..." + context.getJobDetail().getDescription());
        JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
        log.info(mergedJobDataMap.getString("jobDataMapParam"));
    }
}

2.4.4、Controller类

import cn.yx.zg.common.QuartzJobService;
import cn.yx.zg.pojo.QuartzBean;
import org.quartz.JobDataMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@RestController
public class QuartzJobController {

    @Resource
    private QuartzJobService quartzJobService;

    /**
     * 查询定时任务列表
     *
     * @return
     */
    @GetMapping("get")
    public List<QuartzBean> getQuartzList() {
        return quartzJobService.getScheduleJobList();
    }

    /**
     * 创建简单的任务
     *
     * @param jobName        任务名称
     * @param jobGroup       任务组名称
     * @param jobDescription 任务描述
     * @return
     * @throws Exception
     */
    @GetMapping("createSimpleJob")
    public String createSimpleJob(String jobName, String jobGroup, String jobDescription) throws Exception {
        QuartzBean quartzBean = new QuartzBean();
        quartzBean.setJobClass("cn.yx.zg.task.MyTask");
        quartzBean.setJobName(jobName);
        quartzBean.setJobGroup(jobGroup);
        quartzBean.setJobDescription(jobDescription);

        JobDataMap map = new JobDataMap();
        map.put("jobDataMapParam", "aaa");
        quartzBean.setJobDataMap(map);
        //10s中后开始
        Calendar newTimeStart = Calendar.getInstance();
        newTimeStart.setTime(new Date());
        newTimeStart.add(Calendar.SECOND, 10);
        quartzBean.setStartTime(newTimeStart.getTime());
        //50s后结束
        Calendar newTimeEnd = Calendar.getInstance();
        newTimeEnd.setTime(new Date());
        newTimeEnd.add(Calendar.SECOND, 50);
        quartzBean.setEndTime(newTimeEnd.getTime());
        quartzBean.setEndTime(null);
        //每隔3秒钟一次
        quartzBean.setInterval(3);
        quartzJobService.createScheduleSimpleJob(quartzBean);
        return "SUCCESS";
    }

    /**
     * 获取任务状态
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    @GetMapping("/getScheduleJobStatus")
    public String getScheduleJobStatus(String jobName, String jobGroup) throws Exception {
        /**
         * ("BLOCKED", " 阻塞 ");
         * ("COMPLETE", "完成");
         * ("ERROR", "出错");
         * ("NONE", "不存在");
         * ("NORMAL", "正常");
         * ("PAUSED", "暂停");
         */
        return quartzJobService.getScheduleJobStatus(jobName, jobGroup);
    }

    /**
     * 创建Cron的任务
     *
     * @param jobName
     * @param jobGroup
     * @param jobDescription
     * @return
     * @throws Exception
     */
    @GetMapping("/createCronJob")
    public String createCronJob(String jobName, String jobGroup, String jobDescription) throws Exception {
        QuartzBean quartzBean = new QuartzBean();
        quartzBean.setJobClass("cn.yx.zg.task.MyTask");
        quartzBean.setJobName(jobName);
        quartzBean.setJobGroup(jobGroup);
        quartzBean.setJobDescription(jobDescription);
        quartzBean.setCronExpression("*/10 * * * * ?");
        JobDataMap map = new JobDataMap();
        map.put("jobDataMapParam", "aaa");
        quartzBean.setJobDataMap(map);
        quartzJobService.createScheduleCronJob(quartzBean);
        return "SUCCESS";
    }

    /**
     * 删除任务
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/delete")
    public String delete(String jobName, String jobGroup) throws Exception {
        quartzJobService.deleteScheduleJob(jobName, jobGroup);
        return "SUCCESS";
    }

    /**
     * 立即执行定时任务
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/runJob")
    public String runJob(String jobName, String jobGroup) throws Exception {
        quartzJobService.runJob(jobName, jobGroup);
        return "SUCCESS";
    }

    /**
     * 暂停定时任务
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    @GetMapping(value = "/pauseScheduleJob")
    public String pauseScheduleJob(String jobName, String jobGroup) throws Exception {
        quartzJobService.pauseScheduleJob(jobName, jobGroup);
        return "SUCCESS";
    }

    /**
     * 校验定时任务是否存在
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws Exception
     */
    @GetMapping(value = "check")
    public String check(String jobName, String jobGroup) throws Exception {
        if (quartzJobService.checkExistsScheduleJob(jobName, jobGroup)) {
            return "存在定时任务:" + jobName;
        } else {
            return "不存在定时任务:" + jobName;
        }
    }

    /**
     * 更新定时任务,写法是一样的,直接调用quartzJobService里更新的方法即可
     */
}

3、一些理解

3.1、Quartz的集群原理以及配置?

只要在application.yml文件中配置是否为开启集群即可,Quartz的集群是通过mysql表控制的,集群节点相互之间不通信,而是通过定时任务持久化加锁的方式来实现集群。
对开发人员来说,并不需要管理集群模式下的Quartz。

你可能感兴趣的:(spring,boot,后端,java)