Quartz持久化

1、为什么需要ouartz持久化

  • Quartz持久化即将定时任务保存在介质中,持久化目的是保证任务在发生异常后也不会丢失
  • Quartz默认将定时任务存在内存(RAM]obstore),优点是数据读取速度块,缺点是一旦异常发生,任务 数据就没有了
  • Quartz还提供另外一种存储在数据库的方案(JDBCJobstore)解决上面的问题。

2、如何实现JDBCJobstore

2.1、准备工作

数据库脚本:Quartz的GitHub官网找到对应的sql 脚本,目前可以支持mysql,DB2,oracle等主流的数据库 https://github.com/quartz-scheduler/quartz/releases/
使用 quartz-core \ src \ main \ resources\ org \ quartz \ impl \ jdbcjobstore \ tables_mysql_ innodb.sql ,在自己的数据库中执行这个脚本

2.2、实现任务持久化

  • 数据源: druid-spring-boot-starter 驱动程序:mysql-connector-java
  • ORM框架:mybatis-plus v3.5.5
  • 数据源配置:application.yml
  • quartz存储设置:
    • 默认存储到memory
      • spring.quartz.job-store-type=jdbc
    • #always-每次先清空数据库进行初始化
    • #embedded-只初始化内存数据库,默认值
    • #never-不进行初始化
      spring.quartz.jdbc.initialize-schema=always
  • 任务详细消息的持久化设置:storeDurably()
  • 项目中配置的是cron 触发器,涉及到记录
    • qrtz_cron_triggers、qrtz_job_details、qrtz_triggers 三表

代码演示:
前言:

//引入pom 文件
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

1、配置文件:

    ###############################定时任务 配置############################
  quartz:
#    任务执行类型是存储在数据库中 默认是memory
    job-store-type: JDBC
    jdbc:
#      初始化,每次清空数据库,进行初始化。
      initialize-schema: ALWAYS
#      初始化,内存数据库,默认值
#      initialize-schema: embedded
      #不进行出初始化,会执行从上一次保存得到数据,进行执行
#      initialize-schema: never

2、将表插入到自己的数据库中 或者 ( quartz-core \ src \ main \ resources\ org \ quartz \ impl \ jdbcjobstore \ tables_mysql_ innodb.sql )在自己的数据库中执行这个脚本。

#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.

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;

3、自己的任务类

@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务开始执行");
        JobDetail jobDetail = context.getJobDetail();
        System.out.println("名字" + jobDetail.getKey().getName());
        System.out.println("类名--->" + jobDetail.getJobClass().getName());
        System.out.println("本次执行的时间为---》" + context.getFireTime());
        System.out.println("下次执行的时间为---》" + context.getNextFireTime());
        Object count = jobDetail.getJobDataMap().get("count");
        System.out.println("打印共享数据的次数count--》"+ count);
        count = (Integer) count + 1;
        jobDetail.getJobDataMap().put("count",count);
        System.out.println("任务执行完毕");
        System.out.println("============================");
    }
}

4、定时任务配置

@Configuration
public class QuartzConfiguration {

    //JobDetail
     @Bean(value = "jobDetail")
    public JobDetail jobDetail(){
    return JobBuilder.newJob(MyJob.class)
            .storeDurably()
            //唯一标识
            .withIdentity("jobDetail")
            .usingJobData("count",1)
            .build();
    }
    @Bean
    //Trigger
    public Trigger trigger(@Qualifier("jobDetail")JobDetail jobDetail){
        Trigger jobDetail1 = TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                //唯一标识和上面的JobDetail是配对的。
                .withIdentity("jobDetail")
                //这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
                //每两秒钟执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        return jobDetail1;
    }

}

5、测试

5.1、如果配置文件中 initialize-schema: ALWAYS 每次都初始化。共享数据count每次都是从1开始。

在这里插入图片描述

5.2、如果服务器开始时,配置文件中 initialize-schema: ALWAYS 。当服务器关闭时 将配置文件 中的 initialize-schema: never,服务器再次开启时,count的数值会从上一次服务器停止的count 的值继续往下加。

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

3、完整的配置文件—>工作中开箱即用

    ###############################定时任务 配置############################
spring:
  quartz:
    properties:
      org:
        quartz:
          scheduler:
            instanceName: ${INSTANCE_NAME:confServiceQuartzScheduler}
            instanceId: AUTO
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            isClustered: ${IS_CLUSTERED:true}
            clusterCheckinInterval: 10000
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true
#    任务执行类型是存储在数据库中 默认是memory
    job-store-type: JDBC
    jdbc:
#      初始化,每次清空数据库,进行初始化。
      initialize-schema: always
#      初始化,内存数据库,默认值
#      initialize-schema: embedded
      #不进行出初始化,会执行从上一次保存得到数据,进行执行
#      initialize-schema: never
#会覆盖上一次的任务,count也会从1开始
    overwrite-existing-jobs: true

相关推荐

  1. <span style='color:red;'>Quartz</span>

    Quartz

    2024-06-07 16:08:03      41 阅读
  2. Quartz的分布式功能设计

    2024-06-07 16:08:03       37 阅读
  3. 持久存储 StorageClass

    2024-06-07 16:08:03       46 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 16:08:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 16:08:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 16:08:03       87 阅读
  4. Python语言-面向对象

    2024-06-07 16:08:03       96 阅读

热门阅读

  1. 48、Flink 的 Data Source API 详解

    2024-06-07 16:08:03       32 阅读
  2. QT 和VS 针对linux开发的不同

    2024-06-07 16:08:03       35 阅读
  3. Apache Kylin新手小白入门教程

    2024-06-07 16:08:03       29 阅读
  4. LeetCode刷题第2题

    2024-06-07 16:08:03       27 阅读
  5. 【Python】使用 Python 查询域名的 IP 地址

    2024-06-07 16:08:03       34 阅读
  6. LoRa技术在物联网中的应用

    2024-06-07 16:08:03       31 阅读
  7. 迁移学习的简要概述

    2024-06-07 16:08:03       30 阅读
  8. 【小米-小爱】多模态算法岗社招面经

    2024-06-07 16:08:03       33 阅读
  9. wpf INotifyPropertyChanged

    2024-06-07 16:08:03       29 阅读
  10. 以下哪项不属于盗用视频行为?

    2024-06-07 16:08:03       26 阅读