zoukankan      html  css  js  c++  java
  • Quartz自动化配置集成

    出处:https://www.jianshu.com/p/49133c107143

    定时任务在企业项目比较常用到,几乎所有的项目都会牵扯该功能模块,定时任务一般会处理指定时间点执行某一些业务逻辑、间隔时间执行某一些业务逻辑等。

    在新版本的SpringBoot2.0发布后,针对Quartz新版本进行了 AutoConfiguration自动化配置,省去了很多繁琐的配置。

    本章节我们将详细讲解如何使用外置的Quartz以及SpringBoot的Quartz自动化配置。

    这里采用的是Quartz2.3.0版本,针对该版本,这里列出oracle与mysql的建表语句:

    1. oracle

    -- 存储每一个已配置的 Job 的详细信息
    CREATE TABLE qrtz_job_details
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        JOB_NAME  VARCHAR2(200) NOT NULL,
        JOB_GROUP VARCHAR2(200) NOT NULL,
        DESCRIPTION VARCHAR2(250) NULL,
        JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
        IS_DURABLE VARCHAR2(1) NOT NULL,
        IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
        IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
        REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
        JOB_DATA BLOB NULL,
        CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
    );
    --  存储已配置的 Trigger 的信息
    CREATE TABLE qrtz_triggers
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        JOB_NAME  VARCHAR2(200) NOT NULL, 
        JOB_GROUP VARCHAR2(200) NOT NULL,
        DESCRIPTION VARCHAR2(250) NULL,
        NEXT_FIRE_TIME NUMBER(13) NULL,
        PREV_FIRE_TIME NUMBER(13) NULL,
        PRIORITY NUMBER(13) NULL,
        TRIGGER_STATE VARCHAR2(16) NOT NULL,
        TRIGGER_TYPE VARCHAR2(8) NOT NULL,
        START_TIME NUMBER(13) NOT NULL,
        END_TIME NUMBER(13) NULL,
        CALENDAR_NAME VARCHAR2(200) NULL,
        MISFIRE_INSTR NUMBER(2) NULL,
        JOB_DATA BLOB NULL,
        CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) 
          REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) 
    );
    -- 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
    CREATE TABLE qrtz_simple_triggers
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        REPEAT_COUNT NUMBER(7) NOT NULL,
        REPEAT_INTERVAL NUMBER(12) NOT NULL,
        TIMES_TRIGGERED NUMBER(10) NOT NULL,
        CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    );
    -- 存储 Cron Trigger,包括 Cron 表达式和时区信息
    CREATE TABLE qrtz_cron_triggers
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        CRON_EXPRESSION VARCHAR2(120) NOT NULL,
        TIME_ZONE_ID VARCHAR2(80),
        CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
          REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    );
    CREATE TABLE qrtz_simprop_triggers
      (          
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        STR_PROP_1 VARCHAR2(512) NULL,
        STR_PROP_2 VARCHAR2(512) NULL,
        STR_PROP_3 VARCHAR2(512) NULL,
        INT_PROP_1 NUMBER(10) NULL,
        INT_PROP_2 NUMBER(10) NULL,
        LONG_PROP_1 NUMBER(13) NULL,
        LONG_PROP_2 NUMBER(13) NULL,
        DEC_PROP_1 NUMERIC(13,4) NULL,
        DEC_PROP_2 NUMERIC(13,4) NULL,
        BOOL_PROP_1 VARCHAR2(1) NULL,
        BOOL_PROP_2 VARCHAR2(1) NULL,
        CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
          REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    );
    -- Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,<span style="color:#800080;">JobStore</span> 并不知道如何存储实例的时候)
    CREATE TABLE qrtz_blob_triggers
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        BLOB_DATA BLOB NULL,
        CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
            REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    );
    -- 以 Blob 类型存储 Quartz 的 Calendar 信息
    CREATE TABLE qrtz_calendars
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
        CALENDAR BLOB NOT NULL,
        CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
    );
    -- 存储已暂停的 Trigger 组的信息 
    CREATE TABLE qrtz_paused_trigger_grps
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
        CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
    );
    -- 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息
    CREATE TABLE qrtz_fired_triggers 
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        ENTRY_ID VARCHAR2(95) NOT NULL,
        TRIGGER_NAME VARCHAR2(200) NOT NULL,
        TRIGGER_GROUP VARCHAR2(200) NOT NULL,
        INSTANCE_NAME VARCHAR2(200) NOT NULL,
        FIRED_TIME NUMBER(13) NOT NULL,
        SCHED_TIME NUMBER(13) NOT NULL,
        PRIORITY NUMBER(13) NOT NULL,
        STATE VARCHAR2(16) NOT NULL,
        JOB_NAME VARCHAR2(200) NULL,
        JOB_GROUP VARCHAR2(200) NULL,
        IS_NONCONCURRENT VARCHAR2(1) NULL,
        REQUESTS_RECOVERY VARCHAR2(1) NULL,
        CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
    );
    -- 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
    CREATE TABLE qrtz_scheduler_state 
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        INSTANCE_NAME VARCHAR2(200) NOT NULL,
        LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
        CHECKIN_INTERVAL NUMBER(13) NOT NULL,
        CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
    );
    -- 存储程序的悲观锁的信息(假如使用了悲观锁)
    CREATE TABLE qrtz_locks
      (
        SCHED_NAME VARCHAR2(120) NOT NULL,
        LOCK_NAME  VARCHAR2(40) NOT NULL, 
        CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
    );
     
    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);

    2. mysql

    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))  
    ENGINE=InnoDB;  
      
    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))  
    ENGINE=InnoDB;  
      
    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))  
    ENGINE=InnoDB;  
      
    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(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(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))  
    ENGINE=InnoDB;  
      
    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),  
    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(200) 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(200) 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(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))  
    ENGINE=InnoDB;  
      
    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))  
    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); 

    一、分布式单节点持久化

    采用jobDetail使用Spring Ioc托管方式来完成整合。

    (一)基本配置

    1. 引入依赖

    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <druid.version>1.1.5</druid.version>
            <quartz.version>2.3.0</quartz.version>
    </properties>
    
    <dependencies>
    
        <!--web相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--数据库相关依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--quartz相关依赖-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>${quartz.version}</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>${quartz.version}</version>
        </dependency>
        <!--定时任务需要依赖context模块-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    2. application.yml

    server:
      port: 8082
    
    #数据源
    spring:
      datasource:
        url: jdbc:mysql://192.168.178.5:12345/cloudDB01?useUnicode=true&characterEncoding=UTF-8
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver

    3. QuartzConfiguration

    @Configuration
    @EnableScheduling //开启任务调度
    public class QuartzConfiguration {
    
        /**
         * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory
         * 实现任务实例化方式
         */
        public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
                ApplicationContextAware {
    
            private transient AutowireCapableBeanFactory beanFactory;
    
            @Override
            public void setApplicationContext(final ApplicationContext context) {
                beanFactory = context.getAutowireCapableBeanFactory();
            }
    
            /**
             * 将job实例交给spring ioc托管
             * 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
             * @param bundle
             * @return
             * @throws Exception
             */
            @Override
            protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
                final Object job = super.createJobInstance(bundle);
                /**
                 * 将job实例交付给spring ioc
                 */
                beanFactory.autowireBean(job);
                return job;
            }
        }
    
        /**
         * 配置任务工厂实例
         * @param applicationContext spring上下文实例
         * @return
         */
        @Bean
        public JobFactory jobFactory(ApplicationContext applicationContext)
        {
            /**
             * 采用自定义任务工厂 整合spring实例来完成构建任务
             * see {@link AutowiringSpringBeanJobFactory}
             */
            AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
            jobFactory.setApplicationContext(applicationContext);
            return jobFactory;
        }
    
        /**
         * 配置任务调度器
         * 使用项目数据源作为quartz数据源
         * @param jobFactory 自定义配置任务工厂
         * @return
         * @throws Exception
         */
        @Bean(destroyMethod = "destroy")
        public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception
        {
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            //将spring管理job自定义工厂交由调度器维护
            schedulerFactoryBean.setJobFactory(jobFactory);
            //设置覆盖已存在的任务
            schedulerFactoryBean.setOverwriteExistingJobs(true);
            //项目启动完成后,等待2秒后开始执行调度器初始化
            schedulerFactoryBean.setStartupDelay(2);
            //设置调度器自动运行
            schedulerFactoryBean.setAutoStartup(true);
            //设置数据源,使用与项目统一数据源
            schedulerFactoryBean.setDataSource(dataSource);
            //设置上下文spring bean name
            schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
            //设置配置文件位置
            schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
            return schedulerFactoryBean;
        }
    }

    (1) SchedulerFactoryBean

    官方quartz有两种持久化的配置方案。

    第一种:采用quartz.properties配置文件配置独立的定时任务数据源,可以与使用项目的数据库完全独立。
    第二种:采用与创建项目统一个数据源,定时任务持久化相关的表与业务逻辑在同一个数据库内。

    本章节我们采用的是第二种方案。

    上面创建SchedulerFactoryBean的参数中有一个是DataSource,DataSource会根据application.yml文件内的数据源相关配置自动实例化DataSource实例。

    通过调用SchedulerFactoryBean对象的setConfigLocation方法来设置quartz定时任务框架的基本配置,配置文件所在位置:resources/quartz.properties => classpath:/quartz.properties下。

    注意:quartz.properties配置文件一定要放在classpath下,放在别的位置有部分功能不会生效。

    4. quartz.properties文件的配置

    #调度器实例名称
    org.quartz.scheduler.instanceName = quartzScheduler
    
    #调度器实例编号自动生成
    org.quartz.scheduler.instanceId = AUTO
    
    #持久化方式配置
    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
    
    #持久化方式配置数据驱动,MySQL数据库
    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    
    #quartz相关数据表前缀名
    org.quartz.jobStore.tablePrefix = QRTZ_
    
    #开启分布式部署
    org.quartz.jobStore.isClustered = true
    #配置是否使用
    org.quartz.jobStore.useProperties = false
    
    #分布式节点有效性检查时间间隔,单位:毫秒
    org.quartz.jobStore.clusterCheckinInterval = 20000
    
    #线程池实现类
    org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
    
    #执行最大并发线程数量
    org.quartz.threadPool.threadCount = 10
    
    #线程优先级
    org.quartz.threadPool.threadPriority = 5
    
    #配置为守护线程,设置后任务将不会执行
    #org.quartz.threadPool.makeThreadsDaemons=true
    
    #配置是否启动自动加载数据库内的定时任务,默认true
    org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

    在上面配置中org.quartz.jobStore.class与org.quartz.jobStore.driverDelegateClass是定时任务持久化的关键配置,配置了数据库持久化定时任务以及采用MySQL数据库进行连接,当然这里我们也可以配置其他的数据库,如下所示:

    PostgreSQL : org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    Sybase : org.quartz.impl.jdbcjobstore.SybaseDelegate
    MSSQL : org.quartz.impl.jdbcjobstore.MSSQLDelegate
    HSQLDB : org.quartz.impl.jdbcjobstore.HSQLDBDelegate
    Oracle : org.quartz.impl.jdbcjobstore.oracle.OracleDelegate

    org.quartz.jobStore.tablePrefix属性配置了定时任务数据表的前缀,在quartz官方提供的创建表SQL脚本默认就是qrtz_,在对应的XxxDelegate驱动类内也是使用的默认值,所以这里我们如果修改表名前缀,配置可以去掉。

    org.quartz.jobStore.isClustered属性配置了开启定时任务分布式功能,再开启分布式时对应属性org.quartz.scheduler.instanceId 改成Auto配置即可,实例唯一标识会自动生成。

    (二)测试

    1. 创建一个简单的商品数据表

    DROP TABLE IF EXISTS `basic_good_info`;
    CREATE TABLE `basic_good_info` (
      `BGI_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品编号',
      `BGI_NAME` varchar(20) DEFAULT NULL COMMENT '商品名称',
      `BGI_PRICE` decimal(8,2) DEFAULT NULL COMMENT '单价',
      `BGI_UNIT` varchar(10) DEFAULT NULL COMMENT '单位',
      PRIMARY KEY (`BGI_ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='商品基本信息';

    2. 再来添加一个商品添加的控制器方法

    @RestController
    @RequestMapping(value = "/good")
    public class GoodController
    {
        /**
         * 商品业务逻辑实现
         */
        @Autowired
        private GoodInfoService goodInfoService;
        /**
         * 添加商品
         * @return
         */
        @RequestMapping(value = "/save",method = {RequestMethod.POST})
        public Long save(@RequestBody Map good) throws Exception {
            return goodInfoService.saveGood(good);
        }
    }

    在请求商品添加方法时,我们调用了GoodInfoService内的saveGood方法。

    @Service
    @Transactional(rollbackFor = Exception.class)
    public class GoodInfoService {
        /**
         * 注入任务调度器
         */
        @Autowired
        private Scheduler quartzScheduler;
    
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        /**
         * 保存商品基本信息
         * @param good 商品实例
         * @return
         */
        public Long saveGood(Map good) throws Exception {
            String bgiName = String.valueOf(good.get("name"));
            Double bgiPrice = Double.parseDouble(String.valueOf(good.get("price")));
            String sql = "insert into basic_good_info(BGI_NAME, BGI_PRICE) values('" + bgiName + "', " + bgiPrice + ")";
            Connection conn = jdbcTemplate.getDataSource().getConnection();
            PreparedStatement psmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
            psmt.executeUpdate();
            ResultSet keyResultSet = psmt.getGeneratedKeys();
            keyResultSet.next();
            long num =keyResultSet.getLong(1);
            System.out.println(num);
            //构建创建商品定时任务
            buildCreateGoodTimer();
            //构建商品库存定时任务
            buildGoodStockTimer();
            return num;
        }
    }

    这个只是作为保存商品的操作,后面我们会模拟一个请求,在商品添加完成后1分钟我们通知后续的逻辑进行下一步处理,同时开始商品库存定时检查的任务。

    3. 定义商品添加定时任务

    创建一个任务实例,并且继承org.springframework.scheduling.quartz.QuartzJobBean抽象类,重写父抽象类内的executeInternal方法来实现任务的主体逻辑。

    public class GoodAddTimer extends QuartzJobBean {
        /**
         * logback
         */
        static Logger logger = LoggerFactory.getLogger(GoodAddTimer.class);
    
        /**
         * 定时任务逻辑实现方法
         * 每当触发器触发时会执行该方法逻辑
         *
         * @param jobExecutionContext 任务执行上下文
         * @throws JobExecutionException
         */
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            logger.info("商品添加完成后执行任务,任务时间:{}", new Date());
        }
    }

    4. 定义商品库存检查任务

    继承org.springframework.scheduling.quartz.QuartzJobBean抽象类实现抽象类内的executeInternal方法。

    public class GoodStockCheckTimer extends QuartzJobBean{
        /**
         * logback
         */
        static Logger logger = LoggerFactory.getLogger(GoodStockCheckTimer.class);
    
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            logger.info("执行库存检查定时任务,执行时间:{}",new Date());
        }
    }

    5. 分别将两个任务添加到调度器

    在GoodInfoService类内添加buildCreateGoodTimer方法用于实例化商品添加任务:

      /**
         * 构建创建商品定时任务
         */
        public void buildCreateGoodTimer() throws Exception {
            //设置开始时间为1分钟后
            long startAtTime = System.currentTimeMillis() + 1000 * 60;
            //任务名称
            String name = UUID.randomUUID().toString();
            //任务所属分组
            String group = GoodAddTimer.class.getName();
            //创建任务
            JobDetail jobDetail = JobBuilder.newJob(GoodAddTimer.class).withIdentity(name,group).build();
            //创建任务触发器
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).startAt(new Date(startAtTime)).build();
            //将触发器与任务绑定到调度器内
            quartzScheduler.scheduleJob(jobDetail, trigger);
        }

    在上面方法中我们定义的GoodAddTimer实例只运行一次,在商品添加完成后延迟1分钟进行调用任务主体逻辑。

    在GoodInfoService类内添加buildGoodStockTimer方法用于实例化商品库存检查任务:

        public void buildGoodStockTimer() throws Exception {
            //任务名称
            String name = UUID.randomUUID().toString();
            //任务所属分组
            String group = GoodStockCheckTimer.class.getName();
    
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/30 * * * * ?");
            //创建任务
            JobDetail jobDetail = JobBuilder.newJob(GoodStockCheckTimer.class).withIdentity(name,group).build();
            //创建任务触发器
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).withSchedule(scheduleBuilder).build();
            //将触发器与任务绑定到调度器内
            quartzScheduler.scheduleJob(jobDetail, trigger);
        }

    该任务的触发器我们采用了cron表达式来设置,每隔30秒执行一次任务主体逻辑。

    注:任务的名称以及任务的分组是为了区分任务做的限制,在同一个分组下如果加入同样名称的任务,则会提示任务已经存在,添加失败的提示。

    6. 单元测试

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {QuartzApplication.class})
    public class QuartzApplicationTests {
        /**
         * 模拟mvc测试对象
         */
        private MockMvc mockMvc;
    
        /**
         * web项目上下文
         */
        @Autowired
        private WebApplicationContext webApplicationContext;
    
        /**
         * 所有测试方法执行之前执行该方法
         */
        @Before
        public void before() {
            //获取mockmvc对象实例
            mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        }
    
        /**
         * 测试添加商品
         *
         * @throws Exception
         */
        @Test
        public void addGood() throws Exception {
            Map params = new HashMap();
            params.put("name", "西瓜");
            params.put("unit","斤");
            params.put("price", "12.88");
            String requestJson = JSONObject.toJSONString(params);
            MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/good/save")
                    .contentType(MediaType.APPLICATION_JSON).content(requestJson))
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(MockMvcResultMatchers.status().is(200))
                    .andReturn();
            result.getResponse().setCharacterEncoding("UTF-8");
            System.out.println(result.getResponse().getContentAsString());
        }
    }

     执行后,看看QRTZ_CRON_TRIGGERS、QRTZ_FIRED_TRIGGERS、QRTZ_JOB_DETAILS、QRTZ_LOCKS等表是否有数据。

    二、分布式多节点负载持久化

    这里要特别注意任务在持久化到数据库内时会保存任务的全路径,quartz在运行任务时会根据任务全路径去执行,如果不一致则会提示找不到指定类,所以多节点中各个节点的任务路径要一致。

    1. 配置分布式

    在单节点持久化中,其实已经为分布式做好了相关配置。

    (1) org.quartz.scheduler.instanceId : 定时任务的实例编号,如果手动指定需要保证每个节点的唯一性,因为quartz不允许出现两个相同instanceId的节点,我们这里指定为Auto就可以了,我们把生成编号的任务交给quartz。

    (2) org.quartz.jobStore.isClustered: 这个属性才是真正的开启了定时任务的分布式配置,当我们配置为true时quartz框架就会调用ClusterManager来初始化分布式节点。

    (3) org.quartz.jobStore.clusterCheckinInterval:配置了分布式节点的检查时间间隔,单位:毫秒。

    完整的quartz.properties文件:

    #调度器实例名称
    org.quartz.scheduler.instanceName = quartzScheduler
    
    #调度器实例编号自动生成
    org.quartz.scheduler.instanceId = AUTO
    
    #持久化方式配置
    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
    
    #持久化方式配置数据驱动,MySQL数据库
    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    
    #quartz相关数据表前缀名
    org.quartz.jobStore.tablePrefix = QRTZ_
    
    #开启分布式部署
    org.quartz.jobStore.isClustered = true
    #配置是否使用
    org.quartz.jobStore.useProperties = false
    
    #分布式节点有效性检查时间间隔,单位:毫秒
    org.quartz.jobStore.clusterCheckinInterval = 10000
    
    #线程池实现类
    org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
    
    #执行最大并发线程数量
    org.quartz.threadPool.threadCount = 10
    
    #线程优先级
    org.quartz.threadPool.threadPriority = 5
    
    #配置为守护线程,设置后任务将不会执行
    #org.quartz.threadPool.makeThreadsDaemons=true
    
    #配置是否启动自动加载数据库内的定时任务,默认true
    org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

    当我们启动任务节点时,会根据org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread属性配置进行是否自动加载任务,默认true自动加载数据库内的任务到节点。

    按照上面单节点quartz-first,新建一个叫做quartz-second的节点,这样就有两个节点了。两个节点需要做以下修改:

    • quartz-second修改application.yml的端口,使其与quartz-first不同
    • quartz-first和quartz-second修改任务的输出日志,添加一些代表各自节点的输出日志,如添加quartz-first或quartz-second的日志

    启动quartz-first和quartz-second项目,在控制台日志中可以看出类似以下的日志,那是自动分配的实例id:

    Scheduler quartzScheduler_$_SKY-20190903YUM1573950650675 started.

    我们发现如果两个节点同时启动,哪个节点先把节点信息注册到数据库就获得了优先执行权,另外一个节点不会执行,相当于是备份的。当这个正在执行的节点宕掉了,这个节点就会接收调度任务。这就是quartz与schedule的一个很大区别,它已经实现了分布式的任务调度了,不会有多个节点重复执行任务的情况。

    2. 传递参数到任务

    我们平时在使用任务时,如果是针对性比较强的业务逻辑,肯定需要特定的参数来完成业务逻辑的实现。这个就要使用JobDataMap来实现了。

    //1. 通过JobDetail获取一个JobDataMap,并往其中添加我们要传递的参数
    jobDetail.getJobDataMap().put("goodId",goodId);
    
    //2. 在任务调度的主方法executeInternal(JobExecutionContext jobExecutionContext)会传入JobExecutionContext 上下文,我们可以通过这个获取传递的参数值
    JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();
    Long goodId = dataMap.getLong("goodId");

    三、SpringBoot的Quartz配置自动化

    在SpringBoot2.0后,针对Quartz进行了 AutoConfiguration自动化配置,省去了很多繁琐的配置。

    此操作都是在上面的项目基础上做改造。

    1. 修改pom.xml依赖

    <!--quartz相关依赖-->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>${quartz.version}</version>
    </dependency>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz-jobs</artifactId>
        <version>${quartz.version}</version>
    </dependency>
    >>>>替换为:>>>>
    <!--quartz依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

    2. 删除QuartzConfiguration配置类

    之前我们使用QuartzConfiguration配置类来完成了Quartz需要的一系列配置,如:JobFactory、SchedulerFactoryBean等,在我们添加spring-boot-starter-quartz依赖后就不需要主动声明工厂类,因为spring-boot-starter-quartz已经为我们自动化配置好了。

    3.自动化源码

    我们找到spring-boot-autoconfigure-x.x.x.RELEASE.jar,找到org.springframework.boot.autoconfigure.quartz,该目录就是SpringBoot为我们提供的Quartz自动化配置源码实现,在该目录下有如下所示几个类:

    • AutowireCapableBeanJobFactory

      该类替代了我们之前在QuartzConfiguration配置类的AutowiringSpringBeanJobFactory内部类实现,主要作用是我们自定义的QuartzJobBean子类被Spring IOC进行托管,可以在定时任务类内使用注入任意被Spring IOC托管的类。

    • JobStoreType

      该类是一个枚举类型,定义了对应application.yml、application.properties文件内spring.quartz.job-store-type配置,其目的是配置quartz任务的数据存储方式,分别为:MEMORY(内存方式:默认)、JDBC(数据库方式)。

    • QuartzAutoConfiguration

    该类是自动配置的主类,内部配置了SchedulerFactoryBean以及JdbcStoreTypeConfiguration,使用QuartzProperties作为属性自动化配置条件。

    • QuartzDataSourceInitializer

    该类主要用于数据源初始化后的一些操作,根据不同平台类型的数据库进行选择不同的数据库脚本。

    • QuartzProperties

    该类对应了spring.quartz在application.yml、application.properties文件内开头的相关配置。

    • SchedulerFactoryBeanCustomizer

    这是一个接口,我们实现该接口后并且将实现类使用Spring IOC托管,可以完成SchedulerFactoryBean的个性化设置,这里的设置完全可以对SchedulerFactoryBean做出全部的设置变更。

    4.spring.quartz配置

    application.yml配置:

    spring:
      quartz:
        #相关属性配置
        properties:
          org:
            quartz:
              scheduler:
                instanceName: clusteredScheduler
                instanceId: AUTO
              jobStore:
                class: org.quartz.impl.jdbcjobstore.JobStoreTX
                driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
                tablePrefix: QRTZ_
                isClustered: true
                clusterCheckinInterval: 10000
                useProperties: false
              threadPool:
                class: org.quartz.simpl.SimpleThreadPool
                threadCount: 10
                threadPriority: 5
                threadsInheritContextClassLoaderOfInitializingThread: true
        #数据库方式
        job-store-type: jdbc
        #初始化表结构
        #jdbc:
          #initialize-schema: never

    上面的spring.quartz.properties:

    该配置其实代替了之前的quartz.properties,我们把之前quartz.properties配置文件内的所有配置转换成YAML风格,对应的添加在该配置下即可,在QuartzAutoConfiguration类内,会自动调用SchedulerFactoryBean的setQuartzProperties方法,把spring.quartz.properties内的所有配置进行设置。

    @Bean
    @ConditionalOnMissingBean
    public SchedulerFactoryBean quartzScheduler() {
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(this.applicationContext.getAutowireCapableBeanFactory()));
            // 如果配置了spring.quartz.properties
            if (!this.properties.getProperties().isEmpty()) {
            //  将所有properties设置到QuartzProperties
                schedulerFactoryBean.setQuartzProperties(this.asProperties(this.properties.getProperties()));
            }
    ......省略部分代码

    spring.quartz.job-store-type:设置quartz任务的数据持久化方式,默认是内存方式,我们这里沿用之前的方式,配置JDBC以使用数据库方式持久化任务。

  • 相关阅读:
    分治法的经典问题——大整数相乘
    分治法的经典问题——大整数相乘
    L2-013. 红色警报(dfs)
    L2-013. 红色警报(dfs)
    L2-012. 关于堆的判断
    L2-012. 关于堆的判断
    二进制和位运算中的异或
    2015年天勤考研机试模拟赛 A 推断三角形
    怎样利用kettle官方社区查找关于carte服务的设置
    openCV中 libopencv-nonfree-dev的安装: undefined reference to `cv::initModule_nonfree()&#39;
  • 原文地址:https://www.cnblogs.com/myitnews/p/11863506.html
Copyright © 2011-2022 走看看