SpringBoot集成Quartz实现定时任务

文章目录

  • Quartz简介
  • pom依赖
  • 内存方式存储
  • Quartz简介
  • pom依赖
  • 内存方式存储
  • 数据库方式存储
  • 分布式任务支持

Quartz简介

Quartz的快速入门见:
Quartz官方文档_w3cschool

Quartz 存储方式有两种:MEMORY 和 JDBC。默认是内存形式维护任务信息,服务重启了任务就重新开始执行;而JDBC形式就是能够把任务信息持久化到数据库,虽然服务重启了,但根据数据库中的记录,任务还能继续执行。

pom依赖

    
    
        org.springframework.boot
        spring-boot-starter-quartz
    

内存方式存储

  1. 新建工程,pom增加quartz依赖

  2. 新建一个Job类,继承QuartzJobBean,实现抽象类中的方法,方法中实现该定时任务需要执行的逻辑。

比如我新建一个PrintTipJob,每次执行时在控制台输出hello world!

package com.example.demo.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class PrintTipJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        LocalTime time = LocalTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        System.out.println("time:" + time.format(formatter) + "  hello world!");
    }
}
  1. 封装一个用于增加,更新,删除job的service层

    • Job 表示一个工作,要执行的具体内容。此接口中只有一个方法:void execute(JobExecutionContext context)
    • JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外JobDetail 还包含了这个任务调度的方案和策略。
    • Trigger 代表一个调度参数的配置,什么时候去调。
    • Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

service的接口

package com.example.demo.service;

import org.springframework.scheduling.quartz.QuartzJobBean;

public interface QuartzJobService {

   /**
    * 添加一个任务
    * @param job
    * @param jobName
    * @param jobGroupName
    * @param jobCronTime
    */
   void addJob(Class<? extends QuartzJobBean> job, String jobName, String jobGroupName, String jobCronTime);

   /**
    * 更新任务的执行cron
    * @param job
    * @param jobGroupName
    * @param jobCronTime
    */
   void updateJob(String job, String jobGroupName, String jobCronTime);

   /**
    * 是否存在某个job
    * @param job
    * @param jobGroupName
    * @return
    */
   boolean existJob(String job, String jobGroupName);

   /**
    * 删除任务一个job
    *
    * @param jobName      任务名称
    * @param jobGroupName 任务组名
    */
   void deleteJob(String jobName, String jobGroupName);
}

service实现类

package com.example.demo.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.example.demo.service.QuartzJobService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

import java.util.Set;

@Slf4j
@Service
public class QuartzJobServiceImpl implements QuartzJobService {

    @Autowired
    private Scheduler scheduler;

    @Override
    public void addJob(Class<? extends QuartzJobBean> job, String jobName, String jobGroupName, String jobCronTime) {
        JobDetail jobDetail = JobBuilder.newJob(job)
                .withIdentity(jobName, jobGroupName)
                .withDescription(jobCronTime)
                .build();

        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).startNow().build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
    }

    @Override
    public void updateJob(String job, String jobGroupName, String jobCronTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(job, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (ObjectUtil.isNotNull(trigger)) {
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                        .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).build();
            } else {
                trigger = TriggerBuilder.newTrigger().withIdentity(job, jobGroupName)
                        .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                        .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).startNow().build();
            }

            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            log.error("e:{}", e.getMessage());
        }
    }

    @Override
    public boolean existJob(String job, String jobGroupName) {
        try {
            if (StringUtils.isAnyBlank(job, jobGroupName)) {
                return false;
            }
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            if (CollectionUtils.isNotEmpty(jobKeys)) {
                for (JobKey jobKey : jobKeys) {
                    if (jobKey.getName().equals(job) && jobKey.getGroup().equals(jobGroupName)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
        return false;
    }

    @Override
    public void deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(new JobKey(jobName, jobGroupName));
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
    }
}

  1. 创建定时任务监听类,实现ApplicationListener接口,服务一启动时,就增加或更新job

增加PrintTipJob类,cron表达式0/5 * * * * ? ,每5s执行一次

给出一个cron表达式在线生成器小工具的链接:Cron在线表达式生成器

package com.example.demo.listener;

import com.example.demo.job.PrintTipJob;
import com.example.demo.service.QuartzJobService;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent> {

    @Resource
    private QuartzJobService quartzJobService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (quartzJobService.existJob("PrintTipJob", "test")) {
            quartzJobService.updateJob("PrintTipJob", "test", "0/5 * * * * ? ");
        } else {
            quartzJobService.addJob(PrintTipJob.class, "PrintTipJob", "test", "0/5 * * * * ? ");
        }
    }
}

  1. 启动工程,可以看到控制台每隔5s会打印

图1SpringBoot集成Quartz实现定时任务

Quartz简介

Quartz的快速入门见:
Quartz官方文档_w3cschool

Quartz 存储方式有两种:MEMORY 和 JDBC。默认是内存形式维护任务信息,服务重启了任务就重新开始执行;而JDBC形式就是能够把任务信息持久化到数据库,虽然服务重启了,但根据数据库中的记录,任务还能继续执行。

pom依赖

    
    
        org.springframework.boot
        spring-boot-starter-quartz
    

内存方式存储

  1. 新建工程,pom增加quartz依赖

  2. 新建一个Job类,继承QuartzJobBean,实现抽象类中的方法,方法中实现该定时任务需要执行的逻辑。

比如我新建一个PrintTipJob,每次执行时在控制台输出hello world!

package com.example.demo.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class PrintTipJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        LocalTime time = LocalTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        System.out.println("time:" + time.format(formatter) + "  hello world!");
    }
}
  1. 封装一个用于增加,更新,删除job的service层

    • Job 表示一个工作,要执行的具体内容。此接口中只有一个方法:void execute(JobExecutionContext context)
    • JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外JobDetail 还包含了这个任务调度的方案和策略。
    • Trigger 代表一个调度参数的配置,什么时候去调。
    • Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

service的接口

package com.example.demo.service;

import org.springframework.scheduling.quartz.QuartzJobBean;

public interface QuartzJobService {

   /**
    * 添加一个任务
    * @param job
    * @param jobName
    * @param jobGroupName
    * @param jobCronTime
    */
   void addJob(Class<? extends QuartzJobBean> job, String jobName, String jobGroupName, String jobCronTime);

   /**
    * 更新任务的执行cron
    * @param job
    * @param jobGroupName
    * @param jobCronTime
    */
   void updateJob(String job, String jobGroupName, String jobCronTime);

   /**
    * 是否存在某个job
    * @param job
    * @param jobGroupName
    * @return
    */
   boolean existJob(String job, String jobGroupName);

   /**
    * 删除任务一个job
    *
    * @param jobName      任务名称
    * @param jobGroupName 任务组名
    */
   void deleteJob(String jobName, String jobGroupName);
}

service实现类

package com.example.demo.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.example.demo.service.QuartzJobService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

import java.util.Set;

@Slf4j
@Service
public class QuartzJobServiceImpl implements QuartzJobService {

    @Autowired
    private Scheduler scheduler;

    @Override
    public void addJob(Class<? extends QuartzJobBean> job, String jobName, String jobGroupName, String jobCronTime) {
        JobDetail jobDetail = JobBuilder.newJob(job)
                .withIdentity(jobName, jobGroupName)
                .withDescription(jobCronTime)
                .build();

        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).startNow().build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
    }

    @Override
    public void updateJob(String job, String jobGroupName, String jobCronTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(job, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (ObjectUtil.isNotNull(trigger)) {
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                        .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).build();
            } else {
                trigger = TriggerBuilder.newTrigger().withIdentity(job, jobGroupName)
                        .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                        .withSchedule(CronScheduleBuilder.cronSchedule(jobCronTime)).startNow().build();
            }

            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            log.error("e:{}", e.getMessage());
        }
    }

    @Override
    public boolean existJob(String job, String jobGroupName) {
        try {
            if (StringUtils.isAnyBlank(job, jobGroupName)) {
                return false;
            }
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            if (CollectionUtils.isNotEmpty(jobKeys)) {
                for (JobKey jobKey : jobKeys) {
                    if (jobKey.getName().equals(job) && jobKey.getGroup().equals(jobGroupName)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
        return false;
    }

    @Override
    public void deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(new JobKey(jobName, jobGroupName));
        } catch (Exception e) {
            log.error("e:{}", e.getMessage());
        }
    }
}

  1. 创建定时任务监听类,实现ApplicationListener接口,服务一启动时,就增加或更新job

增加PrintTipJob类,cron表达式0/5 * * * * ? ,每5s执行一次

给出一个cron表达式在线生成器小工具的链接:Cron在线表达式生成器

package com.example.demo.listener;

import com.example.demo.job.PrintTipJob;
import com.example.demo.service.QuartzJobService;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent> {

    @Resource
    private QuartzJobService quartzJobService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (quartzJobService.existJob("PrintTipJob", "test")) {
            quartzJobService.updateJob("PrintTipJob", "test", "0/5 * * * * ? ");
        } else {
            quartzJobService.addJob(PrintTipJob.class, "PrintTipJob", "test", "0/5 * * * * ? ");
        }
    }
}

  1. 启动工程,可以看到控制台每隔5s会打印

SpringBoot集成Quartz实现定时任务_第1张图片

数据库方式存储

  1. pom需要引入quartz的依赖,同时还要引入数据库的依赖

    com.mchange
    c3p0
    0.9.5.4



    mysql
    mysql-connector-java

  1. 添加 Quartz 配置信息

在application.properties文件中加入相关配置。

# 将 Quartz 持久化方式修改为 jdbc
spring.quartz.job-store-type=jdbc
# 实例名称(默认为quartzScheduler)
spring.quartz.properties.org.quartz.scheduler.instanceName=test_scheduler
# 实例节点 ID 自动生成
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
# 修改存储内容使用的类
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据源信息
spring.quartz.properties.org.quartz.jobStore.dataSource=quartz_jobs
spring.quartz.properties.org.quartz.dataSource.quartz_jobs.driver=com.mysql.cj.jdbc.Driver
spring.quartz.properties.org.quartz.dataSource.quartz_jobs.URL=jdbc:mysql://localhost:3306/quartz_jobs?useUnicode=true&characterEncoding=utf8
spring.quartz.properties.org.quartz.dataSource.quartz_jobs.user=root
spring.quartz.properties.org.quartz.dataSource.quartz_jobs.password=
  1. 添加quartz使用到的库表

下载 Quartz 发布包,下载完成后,解压缩进入 quartz-2.2.3/docs/dbTables 目录,找到匹配数据库的 SQL 文件。

下载地址:
https://www.quartz-scheduler.org/downloads/files/quartz-2.2.3-distribution.tar.gz

使用的是mysql的脚本:tables_mysql.sql,或者使用如下脚本

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

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(200) NOT NULL,
    JOB_GROUP VARCHAR(200) 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)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) 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(200) 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)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) 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)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) 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)
);

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) 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)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB 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)
);

CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) 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(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;

此处执行sql时还遇到了另外一个问题,有些表创建时一直报错:Index column size too large. The maximum column size is 767 bytes.解决方式参考链接:MySQL 建索引时遇到 Specified key was too long; max key length is 767 bytes

  1. 启动服务
    代码无需修改,启动服务,可以看到定时任务正常执行,每隔5s有打印。
    数据库相关的表中,也有了数据。
    在这里插入图片描述

分布式任务支持

可以开启集群配置,让定时任务支持分布式任务,本人未实验过,从其他文章中看到补充在这里。

在 application.properties 文件中,加入 Quartz 集群的配置信息:

# 开启集群,多个 Quartz 实例使用同一组数据库表
spring.quartz.properties.org.quartz.jobStore.isClustered=true

注意 Quartz 使用同一组数据库表作集群时,只需要配置相同的 instanceName 实例名称就可以,例如本次都用 test_scheduler.

 spring.quartz.properties.org.quartz.scheduler.instanceName=test_scheduler

参考文章:
玩转 Spring Boot 集成篇(定时任务框架Quartz)

你可能感兴趣的:(Java框架,后端,java)