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对任务增删改查

在这里插入图片描述

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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/355213.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android 基础技术——Bitmap

笔者希望做一个系列&#xff0c;整理 Android 基础技术&#xff0c;本章是关于 Bitmap Bitmap 内存如何计算 占用内存 宽 * 缩放比例 * 高 * 缩放比例 * 每个像素所占字节 缩放比例 设备dpi/图片所在目录的dpi Bitmap加载优化&#xff1f;不改变图片质量的情况下怎么优化&am…

AlmaLinux上安装Docker

AlmaLinux上安装Docker 文章目录 AlmaLinux上安装Docker一、前言二、具体步骤1、Docker 下载更新系统包索引&#xff1a;添加Docker仓库&#xff1a;安装Docker引擎&#xff1a; 2、Docker服务启动启动Docker服务&#xff1a;设置Docker开机自启&#xff1a; 3、Docker 安装验证…

基于SSM的网络办公系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的网络办公系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

mysql注入联合查询

环境搭建 下载复现漏洞的包 下载小皮面板 将下载好的文件解压在小皮面板的phpstudy_pro\WWW路径下 将这个文件phpstudy_pro\WWW\sqli-labs-php7-master\sql-connections\db-creds.inc 中的密码更改为小皮面板中的密码 选择php版本 在小皮中启动nginx和数据库 使用环回地址访…

java如何处理多线程异常

一、一个线程在执行过程中发生了异常会怎样&#xff1f; 那要看我们是否对这个异常进行了处理&#xff0c;如果处理了&#xff0c;那么线程会继续执行&#xff0c;如果没有处理&#xff0c;那么线程会释放掉自己所持有的锁&#xff0c;退出执行&#xff0c;如果这个线程是主线程…

linux 基于科大讯飞的文字转语音使用

官方文档地址&#xff1a;离线语音合成 Linux SDK 文档 | 讯飞开放平台文档中心 一、SDK下载 1、点击上面官方文档地址的链接&#xff0c;可以跳转到以下界面。 2、点击“普通版”&#xff0c;跳转到以下界面。 3、点击“下载”跳转到以下界面 4、最后&#xff0c;点击“SDK下…

电脑和手机连接酒店的wifi,网络不通导致charles无法抓手机的包

查看苹果手机&#xff0c;连wifi后的ip地址 电脑去ping 手机的ip地址&#xff0c;发现ping不通 解决方案&#xff1a; 应该是酒店wifi的问题&#xff0c;让朋友开个手机热点&#xff0c;电脑和我的手机都连这个热点&#xff0c;就可以抓包了

【vue2】路由之 Vue Router

文章目录 一、安装二、基础使用1、简单的示例2、动态路由2.1 定义动态路径参数2.2 获取动态路径的参数2.3 捕获所有路由 3、嵌套路由4、编程式的导航4.1 router.push4.2 router.replace4.3 router.go(n) 5、命名路由6、重定向 三、进阶1、导航守卫1.1 全局前置守卫1.2 全局后置…

日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

文章目录 使用 docker 在 heroku 上单独部署 vue 前端使用 docker 在 heroku 上单独部署 django 后端创建 heroku 项目构建 Dockerfile设置 settings.pydatabase静态文件管理安全设置applicaiton & 中间件配置 设置 requirements.txtheroku container 部署应用 前后端分别部…

SpringBoot整合Xxl-Job实现异步任务调度中心

目录 一、下载 1、源码 2、项目结构 3、模块说明 二、部署任务调度中心 1、创建数据库xxl-job 2、配置数据库 3、启动admin模块 4、打开任务调度中心 三、SpringBoot整合xxl-job 1、导入依赖 2、配置yml文件 3、配置类 4、启动项目 5、任务配置 6、测试 一、下…

Windows 和 Anolis 通过 Docker 安装 Milvus 2.3.4

Windows 10 通过 Docker 安装 Milvus 2.3.4 一.Windows 安装 Docker二.Milvus 下载1.下载2.安装1.Windows 下安装&#xff08;指定好Docker文件目录&#xff09;2.Anolis下安装 三.数据库访问1.ATTU 客户端下载 一.Windows 安装 Docker Docker 下载 双击安装即可&#xff0c;安…

[嵌入式系统-5]:龙芯1B 开发学习套件 -2- LoongIDE 集成开发环境集成开发环境的安装步骤

目录 一、LoongIDE&#xff08;龙芯开发工具集成环境&#xff09;概述 1.1 概述 二、软件开发环境的安装过程 2.0 注意事项 2.1 步骤1&#xff1a;MingW运行环境 2.2 步骤2&#xff1a;安装LoongIDE 2.3 步骤3&#xff1a;安装MIPS工具链 2.4 配置工具链 2.5 重启电脑…

总结NB-IoT模块和单片机的区别

在学习了NB-IoT模块后&#xff0c;紧接着又学习了单片机系统&#xff0c;单片机和NB-IoT模块有什么不同之处呢&#xff0c;总结为以下几点。 大纲如图&#xff1a; 一、硬件层面 1、采用芯片不同&#xff0c; &#xff08;1&#xff09;封装&#xff1a;封装尺寸、方式不同&a…

Qt应用软件【串口篇】串口通信

文章目录 1.串口概述2.串口传输数据的基本原理电信号的传输过程 3.串口的几个概念数据位&#xff08;Data Bits&#xff09;奇偶校验位&#xff08;Parity Bit&#xff09;停止位&#xff08;Stop Bits&#xff09;流控制&#xff08;Flow Control&#xff09;波特率&#xff0…

第九篇【传奇开心果短博文系列】鸿蒙开发技术点案例示例:ArkUI强大的状态管理机制解读

传奇开心果短博文系列 系列短博文目录鸿蒙开发技术点案例示例系列 短博文目录一、前言二、ArkUI强大的状态管理机制介绍三、以官方helloworld示例为例说明ArkUI的状态定义和管理四、以官方 HelloWorld 示例代码为例说明ArkUI状态依赖和自动更新五、以官方helloworld示例代码为例…

PHP语法

#本来是在学命令执行&#xff0c;所以学了学&#xff0c;后来发现&#xff0c;PHP语法和命令执行的关系好像没有那么大&#xff0c;不如直接学php的一些命令执行函数了。# #但是还是更一下&#xff0c;毕竟还是很多地方都要求掌握php作为脚本语言&#xff0c;所以就学了前面的…

多维时序 | Matlab实现DBO-GRU蜣螂算法优化门控循环单元多变量时间序列预测

多维时序 | Matlab实现DBO-GRU蜣螂算法优化门控循环单元多变量时间序列预测 目录 多维时序 | Matlab实现DBO-GRU蜣螂算法优化门控循环单元多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现DBO-GRU蜣螂算法优化门控循环单元多变量时间序列预…

第四十一周:文献阅读+GAN存在的问题和改进

目录 摘要 Abstract 文献阅读&#xff1a;基于Transformer的时间序列生成对抗网络 现有问题 提出方法 相关前提 GAN&#xff08;生成对抗网络&#xff09; Transformer 方法论 时间序列处理 TTS-GAN &#xff08;基于Transformer的时间序列生成对抗网络&#xff09;…

STM32学习笔记(二) —— 调试串口

我们在调试程序时&#xff0c;经常会使用串口打印相关的调试信息&#xff0c;但是单片机串口不能直接与 PC 端的 USB 接口通讯&#xff0c;需要用到一个USB转串口的芯片来充当翻译的角色。我们使用的开发板上有这个芯片&#xff0c;所以在打印调试信息的时候直接使用USB线连接开…

05.领域驱动设计:认识领域事件,解耦微服务的关键

目录 1、概述 2、领域事件 2.1 如何识别领域事件 1.微服务内的领域事件 2.微服务之间的领域事件 3、领域事件总体架构 3.1 事件构建和发布 3.2 事件数据持久化 3.3 事件总线 (EventBus) 3.4 消息中间件 3.5 事件接收和处理 4、案例 5、总结 1、概述 在事件风暴&a…