Spring Boot 2.x 集成 Quartz,动态管理定时任务(集群管理)

1、quartz 依赖集成
2、数据库准备
3、基本配置
4、新建定时任务
5、定时任务的管理 (增加,删除,暂停,重启,查询)
6、调度主接口 org.quartz.Scheduler 部分方法释义

1、quartz 依赖集成

pom.xml

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

2、数据库准备

quartz-x.x.x.jar 包中的org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql文件

3、基本配置

application.yml

spring:
  quartz:
    job-store-type: jdbc
    # 初始化表
    jdbc:
      initialize-schema: never
    # quartz 属性配置
    properties:
      org:
        quartz:
          scheduler:
            # 如果使用集群,实例名需相同
            instanceName: QuartzScheduler
            # 如果使用集群,id需相同
            instanceId: CLUSTERED
            ....
  • 更多的quartz配置,根据实际业务继续添加

4、新建定时任务

继承 org.springframework.scheduling.quartz.QuartzJobBean即可。
QuartzTestJob.java

import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * QuartzTestJob
 *
 * @author seer
 * @date 2018/10/23 14:47
 */
@Slf4j
public class QuartzTestJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("这里写定时任务业务逻辑。。。");
    }
}

5、定时任务的管理

1)获取当前所有的定时任务信息
    /**
     * 获取任务信息
     */
    public void getAllJob() throws Exception {
        /*
        返回数据格式

            [
              {
                "group_name": [
                  {
                    "job_name": {
                      "job_key": "jobKey",
                      "job_description": "任务描述",
                      "job_class": "任务类",
                      "job_cron_trigger": [
                        {
                          "trigger_key": "triggerKey",
                          "trigger_state": "NORMAL",
                          "trigger_description": "啥时候",
                          "trigger_start_time": "开始时间",
                          "trigger_end_time": "结束时间",
                          "trigger_next_fire_time": "下次触发时间",
                          "trigger_previous_fire_time": "上次触发时间",
                          "trigger_final_fire_time": "最后触发时间",
                          "cron_expression": "* * * * * ?"
                        }
                      ],
                      "job_simple_trigger": [
                        {
                          "trigger_key": "triggerKey",
                          "trigger_state": "PAUSED",
                          "trigger_description": "啥时候",
                          "trigger_start_time": "开始时间",
                          "trigger_end_time": "结束时间",
                          "trigger_next_fire_time": "下次触发时间",
                          "trigger_previous_fire_time": "上次触发时间",
                          "trigger_final_fire_time": "最后触发时间",
                          "repeat_count": "重复次数",
                          "repeat_interval": "间隔时间",
                          "triggered_times": "总触发次数"
                        }
                      ]
                    }
                  }
                ]
              }
            ]

         */

        // 获取有所的组
        List<String> jobGroupNameList = scheduler.getJobGroupNames();
        for (String jobGroupName : jobGroupNameList) {
            GroupMatcher<JobKey> jobKeyGroupMatcher = GroupMatcher.jobGroupEquals(jobGroupName);
            Set<JobKey> jobKeySet = scheduler.getJobKeys(jobKeyGroupMatcher);

            for (JobKey jobKey : jobKeySet) {
                String jobName = jobKey.getName();

                // 获取 job 信息
                JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                String jobDescription = jobDetail.getDescription();
                String jobClass = jobDetail.getClass().getName();

                List<Trigger> triggerList = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggerList) {
                    // 获取 trigger 信息
                    String triggerState = scheduler.getTriggerState(trigger.getKey()).toString();
                    String triggerDescription = trigger.getDescription();
                    String triggerStartTime = trigger.getStartTime().toString();
                    String triggerEndTime = trigger.getEndTime().toString();
                    String triggerNextFireTime = trigger.getNextFireTime().toString();
                    String triggerPreviousFireTime = trigger.getPreviousFireTime().toString();
                    String triggerFinalFireTime = trigger.getFinalFireTime().toString();

                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        continue;
                    }

                    if (trigger instanceof SimpleTrigger) {
                        SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
                        int repeatCount = simpleTrigger.getRepeatCount();
                        long repeatInterval = simpleTrigger.getRepeatInterval();
                        int triggered_times = simpleTrigger.getTimesTriggered();
                        continue;
                    }
                }
            }
        }
    }

2)增加定时任务
    /**
     * 增加任务
     */
    public void addJob() throws SchedulerException {
        Class<? extends Job> jobClass = null;
        String jobDescription = null;
        String jobName = null;
        String jobGroup = null;
        List<Map<String, String>> jobCronTriggerList = null;
        List<Map<String, String>> jobSimpleTriggerList = null;

        JobKey jobKey = new JobKey(jobName, jobGroup);
        if (scheduler.checkExists(jobKey)) {
            // TODO seer 2018/10/26 16:16 任务存在
        }

        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobKey)
                .withDescription(jobDescription)
                .build();

        for (Map<String, String> cronTriggerMap : jobCronTriggerList) {
            TriggerKey triggerKey = new TriggerKey(jobName, jobGroup);
            if (scheduler.checkExists(triggerKey)) {
                // TODO seer 2018/10/26 16:17 触发器存在
            }

            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronTriggerMap.get("cronExpression")).withMisfireHandlingInstructionDoNothing();

            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerKey)
                    .withDescription(cronTriggerMap.get("triggerDescription"))
                    .withSchedule(cronScheduleBuilder)
                    .startAt(new Date(cronTriggerMap.get("triggerStartTime")))
                    .endAt(new Date(cronTriggerMap.get("triggerEndTime")))
                    .build();

            scheduler.scheduleJob(jobDetail, cronTrigger);
        }

        for (Map<String, String> jobSimpleTriggerMap : jobSimpleTriggerList) {
            TriggerKey triggerKey = new TriggerKey(jobName, jobGroup);
            if (scheduler.checkExists(triggerKey)) {
                // TODO seer 2018/10/26 16:17 触发器存在
            }

            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder
                    .repeatMinutelyForTotalCount(Integer.valueOf(jobSimpleTriggerMap.get("repeatCount")), Integer.valueOf(jobSimpleTriggerMap.get("repeatInterval")));

            SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerKey)
                    .withDescription(jobSimpleTriggerMap.get("triggerDescription"))
                    .withSchedule(simpleScheduleBuilder)
                    .startAt(new Date(jobSimpleTriggerMap.get("triggerStartTime")))
                    .endAt(new Date(jobSimpleTriggerMap.get("triggerEndTime")))
                    .build();

            scheduler.scheduleJob(jobDetail, simpleTrigger);
        }
    }

3)暂定任务
  /**
     * 暂停任务
     */
    public void pauseJob() throws SchedulerException {
        JobKey jobKey = null;
        scheduler.pauseJob(jobKey);

        String groupName = null;
        GroupMatcher<JobKey> jobKeyGroupMatcher = GroupMatcher.jobGroupEquals(groupName);
        scheduler.pauseJobs(jobKeyGroupMatcher);


        TriggerKey triggerKey = null;
        scheduler.pauseTrigger(triggerKey);

        GroupMatcher<TriggerKey> triggerKeyGroupMatcher = GroupMatcher.triggerGroupEquals(groupName);
        scheduler.pauseTriggers(triggerKeyGroupMatcher);
    }

4)停止任务
 /**
     * 恢复任务
     */
    public void resumeJob() throws SchedulerException {
        JobKey jobKey = null;
        scheduler.resumeJob(jobKey);

        String groupName = null;
        GroupMatcher<JobKey> jobKeyGroupMatcher = GroupMatcher.jobGroupEquals(groupName);
        scheduler.resumeJobs(jobKeyGroupMatcher);


        TriggerKey triggerKey = null;
        scheduler.resumeTrigger(triggerKey);

        GroupMatcher<TriggerKey> triggerKeyGroupMatcher = GroupMatcher.triggerGroupEquals(groupName);
        scheduler.resumeTriggers(triggerKeyGroupMatcher);
    }

5)删除任务
 /**
     * 删除任务
     */
    public void deleteJob() throws SchedulerException {
        JobKey jobKey = null;
        scheduler.deleteJob(jobKey);

        TriggerKey triggerKey = null;
        scheduler.unscheduleJob(triggerKey);
    }

6、调度主接口 org.quartz.Scheduler 部分方法释义


public interface Scheduler {

    ///////////////////////////////////////////////////////////////////////////
    ///
    /// Scheduler State Management Methods
    ///
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 启动 Scheduler
     */
    void start() throws SchedulerException;

    /**
     * 延迟启动 Scheduler
     */
    void startDelayed(int seconds) throws SchedulerException;

    /**
     * Scheduler 是否启动
     */
    boolean isStarted() throws SchedulerException;

    /**
     * 暂停 Scheduler
     */
    void standby() throws SchedulerException;

    /**
     * Scheduler 是否暂停
     */
    boolean isInStandbyMode() throws SchedulerException;

    /**
     * Scheduler 关闭
     */
    void shutdown() throws SchedulerException;

    /**
     * 等所有的任务完成后 Scheduler 关闭
     */
    void shutdown(boolean waitForJobsToComplete)
            throws SchedulerException;

    /**
     * Scheduler 是否关闭
     */
    boolean isShutdown() throws SchedulerException;

    /**
     * 获取 SchedulerMetaData 对象
     */
    SchedulerMetaData getMetaData() throws SchedulerException;

    /**
     * 获取所有正在执行的 Job
     */
    List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException;

    /**
     * 设置 JobFactory
     */
    void setJobFactory(JobFactory factory) throws SchedulerException;

    /**
     * 获取 ListenerManager
     */
    ListenerManager getListenerManager() throws SchedulerException;

    ///////////////////////////////////////////////////////////////////////////
    ///
    /// Scheduling-related Methods
    ///
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 添加指定的 JobDetail 和 Trigger
     */
    Date scheduleJob(JobDetail jobDetail, Trigger trigger)
            throws SchedulerException;

    /**
     * 添加指定的 Trigger
     */
    Date scheduleJob(Trigger trigger) throws SchedulerException;

    /**
     * 批量添加 JobDetail 和 Trigger
     */
    void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) throws SchedulerException;

    /**
     * 添加有多个 Trigger 的 JobDetail
     */
    void scheduleJob(JobDetail jobDetail, Set<? extends Trigger> triggersForJob, boolean replace) throws SchedulerException;

    /**
     * 删除指定的 Trigger
     */
    boolean unscheduleJob(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 批量删除 Trigger
     */
    boolean unscheduleJobs(List<TriggerKey> triggerKeys)
            throws SchedulerException;

    /**
     * 删除并设置新的 Trigger
     */
    Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger)
            throws SchedulerException;

    /**
     * 添加 JobDetail
     */
    void addJob(JobDetail jobDetail, boolean replace)
            throws SchedulerException;

    /**
     * 添加持久化 JobDetail
     */
    void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling)
            throws SchedulerException;

    /**
     * 删除指定的 JobDetail
     */
    boolean deleteJob(JobKey jobKey)
            throws SchedulerException;

    /**
     * 批量删除 JobDetail
     */
    boolean deleteJobs(List<JobKey> jobKeys)
            throws SchedulerException;

    /**
     * 立即触发指定的 JobDetail
     */
    void triggerJob(JobKey jobKey)
            throws SchedulerException;

    /**
     * 立即触发指定的 JobDetail
     */
    void triggerJob(JobKey jobKey, JobDataMap data)
            throws SchedulerException;

    /**
     * 暂停指定的 JobDetail
     */
    void pauseJob(JobKey jobKey)
            throws SchedulerException;

    /**
     * 暂停 Group 中所有 JobDetail
     */
    void pauseJobs(GroupMatcher<JobKey> matcher) throws SchedulerException;

    /**
     * 暂停指定的 TriggerKey
     */
    void pauseTrigger(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 暂停 Group 中所有 Trigger
     */
    void pauseTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException;

    /**
     * 恢复指定的 JobDetail
     */
    void resumeJob(JobKey jobKey)
            throws SchedulerException;

    /**
     * 恢复 Group 中所有 JobDetail
     */
    void resumeJobs(GroupMatcher<JobKey> matcher) throws SchedulerException;

    /**
     * 恢复指定的 TriggerKey
     */
    void resumeTrigger(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 恢复 Group 中所有 Trigger
     */
    void resumeTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException;

    /**
     * 暂停所有任务
     */
    void pauseAll() throws SchedulerException;

    /**
     * 恢复所有任务
     */
    void resumeAll() throws SchedulerException;

    /**
     * 获取所有 JobGroup 名字
     */
    List<String> getJobGroupNames() throws SchedulerException;

    /**
     * 获取 JobGroup 中所有 JobKey
     */
    Set<JobKey> getJobKeys(GroupMatcher<JobKey> matcher) throws SchedulerException;

    /**
     * 获取 JobDetail 的 Trigger
     */
    List<? extends Trigger> getTriggersOfJob(JobKey jobKey)
            throws SchedulerException;

    /**
     * 获取所有 TriggerGroup
     */
    List<String> getTriggerGroupNames() throws SchedulerException;

    /**
     * 获取 TriggerGroup 中所有 Trigger
     */
    Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> matcher) throws SchedulerException;

    /**
     * 获取所有暂停的 TriggerGroup
     */
    Set<String> getPausedTriggerGroups() throws SchedulerException;

    /**
     * 获取指定的 JobDetail
     */
    JobDetail getJobDetail(JobKey jobKey)
            throws SchedulerException;

    /**
     * 获取指定的 Trigger
     */
    Trigger getTrigger(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 获取指定的 Trigger 的状态
     */
    TriggerState getTriggerState(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 重新识别指定的 Trigger 的状态
     */
    void resetTriggerFromErrorState(TriggerKey triggerKey)
            throws SchedulerException;

    /**
     * 给 Scheduler 添加一个指定的 Calendar
     */
    void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
            throws SchedulerException;

    /**
     * 从 Scheduler 删除 Calendar
     */
    boolean deleteCalendar(String calName) throws SchedulerException;

    /**
     * 根据名称获取 Calendar
     */
    Calendar getCalendar(String calName) throws SchedulerException;

    /**
     * 获取所有的 Calendar
     */
    List<String> getCalendarNames() throws SchedulerException;


    /**
     * 中断指定的 JobDetail
     */
    boolean interrupt(JobKey jobKey) throws UnableToInterruptJobException;

    /**
     * 中断指定的 JobDetail
     */
    boolean interrupt(String fireInstanceId) throws UnableToInterruptJobException;

    /**
     * 检查 JobDetail 是否存在
     */
    boolean checkExists(JobKey jobKey) throws SchedulerException;

    /**
     * 检查 Trigger 是否存在
     */
    boolean checkExists(TriggerKey triggerKey) throws SchedulerException;

    /**
     * 清除所有任务
     */
    void clear() throws SchedulerException;

}


扩展文档:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336