事业单位网站建设工作方案,四川公共资源交易信息网,建立网站需要多少钱稻挺湖南岚鸿有名,wordpress html5模板SpringBoot教程#xff08;二十四#xff09; | SpringBoot实现分布式定时任务之Quartz#xff08;基础#xff09; 简介适用场景Quartz核心概念Quartz 存储方式Quartz 版本类型引入相关依赖开始集成方式一#xff1a;内存方式(MEMORY)存储实现定时任务1. 定义任务类2. 定… SpringBoot教程二十四 | SpringBoot实现分布式定时任务之Quartz基础 简介适用场景Quartz核心概念Quartz 存储方式Quartz 版本类型引入相关依赖开始集成方式一内存方式(MEMORY)存储实现定时任务1. 定义任务类2. 定义任务描述及创建任务触发器3. Quartz的yml配置按需配置 方式二数据库(JDBC)方式存储实现定时任务1. 创建相关表2. 引入mysql相关依赖3. 添加yml配置及相关配置类启动查看 防止并发执行上一周期还没执行完下一周期又开始了 遇到的问题及解决问题1更改 Quartz 的 默认连接池配置问题2找不到名为 quartzDataSource 的数据源问题3jdbcUrl is required with driverClassName问题4url is required with driverClassName 简介
Quartz是一个完全由Java开发的开源任务日程管理系统或称为作业调度框架它能够集成于任何Java应用小到独立的应用大至电子商务系统。 Quartz提供了丰富的调度功能和灵活的配置选项帮助开发者实现复杂的任务调度和定时任务功能。
适用场景
Quartz广泛应用于各种企业级应用系统中如电子商务、金融、物流等领域。 无论是简单的定时任务如定时发送邮件、定时清理临时文件等还是复杂的分布式任务如分布式定时任务调度、任务依赖关系管理等Quartz都能够胜任。
Quartz核心概念
Job作业 Quartz中的任务是一个需要被调度执行的接口任务类需要实现该接口并在execute方法中编写具体的业务逻辑。 JobDetail JobDetail用来绑定Job并为Job实例提供许多属性如名称、组名、Job类名以及JobDataMap等。 JobDetail定义的是任务数据而真正的执行逻辑是在Job中。 Trigger触发器 Trigger是Quartz的触发器它描述了触发Job执行的时间触发规则。 Trigger最常用的触发器类型SimpleTrigger和CronTrigger。 Scheduler调度器 Scheduler是Quartz的调度器它负责基于Trigger设定的时间执行Job。Scheduler是一个容器它装载着任务和触发器。 Quartz 存储方式
Quartz 存储方式有两种MEMORY 和 JDBC。
MEMORY或RAMJobStore这是Quartz的默认存储方式它将任务调度的运行信息保存在内存中。这种方式提供了最佳的性能因为内存中数据访问最快。然而它的不足之处在于缺乏数据的持久性当程序中途停止或系统崩溃时所有运行的信息都会丢失。JDBC这种存储方式允许Quartz通过JDBC将任务调度的运行信息保存到数据库中。使用数据库保存任务调度信息后即使系统崩溃后重新启动任务的调度信息也将得到恢复。因此JDBC存储方式提供了数据的持久性。
Quartz 版本类型
Quartz 版本类型有两种单机版 和 集群版 单机版这是Quartz的默认版本类型 Quartz运行在一个单一的Java虚拟机JVM实例中。它通常使用MEMORY存储方式因为这种方式配置容易且运行速度快。然而单机版Quartz存在单点故障的风险如果应用程序所在的服务器出现故障任务调度将会停止。 集群版集群版Quartz可以在多个JVM实例中运行实现高可用性和负载均衡。在集群版中通常使用JDBC存储方式以便在多个节点之间共享任务调度的数据。这样即使其中一个节点出现故障其他节点仍然可以继续工作从而保证了任务调度的连续性和可靠性。
引入相关依赖
!--quartz定时任务--
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-quartz/artifactId
/dependency开始集成
方式一内存方式(MEMORY)存储实现定时任务
1. 定义任务类
可以通过实现 Job 接口来定义任务也可以通过继承 QuartzJobBean 这个抽象类来定义任务其实 QuartzJobBean 本身也实现了 Job 接口其本质都是实现 Job 接口来定义任务。
我这边定义了两个任务用于后续来说明一下关于调度器Scheduler绑定的不同方式 Scheduler绑定有两种方式一种是使用bena的自动配置一种是Scheduler手动配置。
FirstJob 类
package com.example.springbootfull.quartztest;import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;Slf4j
public class FirstJob extends QuartzJobBean {Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {String now DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss).format(LocalDateTime.now());log.info(手动-FirstJob, 当前的时间: now);}
}
SecondJob 类
package com.example.springbootfull.quartztest;import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;Slf4j
public class SecondJob extends QuartzJobBean {Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {String now DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss).format(LocalDateTime.now());log.info(自动-SecondJob, 当前的时间: now);}
}
2. 定义任务描述及创建任务触发器
方式一Scheduler手动配置 这个例子使用的是触发器类型为Cron package com.example.springbootfull.quartztest.config;import com.example.springbootfull.quartztest.FirstJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;Component
public class JobInit implements ApplicationRunner {private static final String ID MANUAL;Autowiredprivate Scheduler scheduler;Overridepublic void run(ApplicationArguments args) throws Exception {// 配置定时任务的信息例如配置定时任务的名字群组之类的JobDetail jobDetail JobBuilder.newJob(FirstJob.class).withIdentity(ID 01)// 设置Job的标识符.storeDurably()// 使JobDetail持久化.build();//触发器类型CronScheduleBuilder scheduleBuilder CronScheduleBuilder.cronSchedule(0/5 * * * * ? *);// 创建任务触发器Trigger trigger TriggerBuilder.newTrigger().forJob(jobDetail) //指定 定时任务.withIdentity(ID 01Trigger) // 设置Trigger的标识符.withSchedule(scheduleBuilder) //配置触发器类型.startNow() //立即執行一次任務.build();// 手动将触发器与任务绑定到调度器内scheduler.scheduleJob(jobDetail, trigger);}
}
方式二使用bena的自动配置建议这种 这个例子使用的是触发器类型为Simple package com.example.springbootfull.quartztest.config;import com.example.springbootfull.quartztest.SecondJob;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class QuartzConfig {private static final String ID AUTOMATIC;//配置定时任务的信息例如配置定时任务的名字群组之类的Beanpublic JobDetail jobDetail1() {return JobBuilder.newJob(SecondJob.class).withIdentity(ID 01)// 设置Job的标识符.storeDurably()// 使JobDetail持久化.build();}//创建任务触发器Beanpublic SimpleTrigger trigger1() {// 简单的调度计划的构造器SimpleScheduleBuilder scheduleBuilder SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(6) // 频率.repeatForever(); // 无限期地重复执行return TriggerBuilder.newTrigger().forJob(jobDetail1())//指定 定时任务.withIdentity(ID 01Trigger).withSchedule(scheduleBuilder).build();}
}运行启动类以后可以看到如下情况
3. Quartz的yml配置按需配置 yml配置可以更为精细化的调整 存储配置 及 线程池配置 spring:# Quartz 的配置对应 QuartzProperties 配置类quartz:job-store-type: memory # Job 存储器类型。默认为 memory 表示内存可选 jdbc 使用数据库。auto-startup: true # Quartz 是否自动启动startup-delay: 0 # 延迟 N 秒启动wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时是否等待定时任务执行完成。默认为 false 建议设置为 trueoverwrite-existing-jobs: false # 是否覆盖已有 Job 的配置properties: # 添加 Quartz Scheduler 附加属性org:quartz:threadPool:threadCount: 25 # 线程池大小。默认为 10 。threadPriority: 5 # 线程优先级class: org.quartz.simpl.SimpleThreadPool # 线程池类型
# jdbc: # 这里暂时不说明使用 JDBC 的 JobStore 的时候才需要配置方式二数据库(JDBC)方式存储实现定时任务
1. 创建相关表
首先确定maven拉取了 spring-boot-starter-quartz 的依赖再接着到私仓下面找到 你的私仓地址\org\quartz-scheduler\quartz\2.3.2把这个下面的quartz-2.3.2.jar 给解压 然后到这个文件的 “quartz-2.3.2\org\quartz\impl\jdbcjobstore” 下面就可以可以看到 我这边选择的是“tables_mysql_innodb.sql”脚本 内容如下执行以后会出现11张表
#
# In your Quartz properties file, youll need to set
# org.quartz.jobStore.driverDelegateClass org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
# I didnt see this anywhere, so I thought Id 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))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINEInnoDB;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))
ENGINEInnoDB;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))
ENGINEInnoDB;CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINEInnoDB;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; 表的说明
表名称说明qrtz_blob_triggersblog类型存储triggersqrtz_calendars以blog类型存储Calendar信息qrtz_cron_triggers存储cron trigger信息qrtz_fired_triggers存储已触发的trigger相关信息qrtz_job_details存储每一个已配置的job detailsqrtz_locks存储悲观锁的信息qrtz_paused_trigger_grps存储已暂停的trigger组信息qrtz_scheduler_state存储Scheduler状态信息qrtz_simple_triggers存储simple trigger信息qrtz_simprop_triggers存储其他几种trigger信息qrtz_triggers存储已配置的trigger信息
所有的表中都含有一个SCHED_NAME字段对应我们配置的scheduler-name相同 Scheduler-name的节点形成一个 Quartz 集群。
2. 引入mysql相关依赖
!-- MySQL连接 --
dependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactId
/dependency
!--mybatis-plus 这个版本需要指定了因为场景启动器里面没有 --
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.7/version
/dependency3. 添加yml配置及相关配置类
spring:datasource:quartz:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/quartz?serverTimezoneGMT%2B8username: rootpassword: rootquartz:job-store-type: jdbc # 使用数据库存储scheduler-name: hyhScheduler # 相同 Scheduler 名字的节点形成一个 Quartz 集群wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时是否等待定时任务执行完成。默认为 false 建议设置为 truejdbc:initialize-schema: never # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never 表示我们手动创建表结构。properties:org:quartz:# JobStore 相关配置jobStore:# 使用的数据源 (和配置类DataSourceConfiguration的 Bean(name quartzDataSource) 存在直接关系)dataSource: quartzDataSource #class: org.quartz.impl.jdbcjobstore.JobStoreTX # JobStore 实现类driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegatetablePrefix: QRTZ_ # Quartz 表前缀isClustered: true # 是集群模式clusterCheckinInterval: 1000useProperties: false# 线程池相关配置threadPool:threadCount: 25 # 线程池大小。默认为 10 。threadPriority: 5 # 线程优先级class: org.quartz.simpl.SimpleThreadPool # 线程池类型
新建DataSourceConfiguration 配置类 该类为数据源配置类 目前只是配置了quartz 数据源暂不支持多数据源 如需多数据源配置请往下看 package com.example.springbootfull.quartztest.config;import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;import javax.sql.DataSource;/*** 该类为数据源配置类* 目前只是配置了quartz 数据源暂不支持多数据源* 如需多数据源配置请自行补充*/
Configuration
public class DataSourceConfiguration {private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {// 创建 HikariDataSource 对象HikariDataSource dataSource properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();// 设置线程池名if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}/*** 创建 quartz 数据源的配置对象*/PrimaryBean(name quartzDataSourceProperties)ConfigurationProperties(prefix spring.datasource.quartz)// 读取 spring.datasource.quartz 配置到 DataSourceProperties 对象public DataSourceProperties quartzDataSourceProperties() {return new DataSourceProperties();}/*** 创建 quartz 数据源*/Bean(name quartzDataSource)//ConfigurationProperties(prefix spring.datasource.quartz.hikari)QuartzDataSourcepublic DataSource quartzDataSource() {// 获得 DataSourceProperties 对象DataSourceProperties properties this.quartzDataSourceProperties();// 创建 HikariDataSource 对象return createHikariDataSource(properties);}}
启动查看
启动启动类后发现数据库表里面有数据了
防止并发执行上一周期还没执行完下一周期又开始了 使用 DisallowConcurrentExecution 注解这可以确保同一时间只有一个该任务的实例在执行从而避免并发执行带来的问题。 但是这可能会导致任务执行的延迟因为新实例必须等待前一个实例完成。 举例
Slf4j
DisallowConcurrentExecution
public class SecondJob extends QuartzJobBean {Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {JobDetail jobDetail jobExecutionContext.getJobDetail();log.info(------任务名 jobDetail.getKey().getName() ,组名 jobDetail.getKey().getGroup() ------我是要执行的定时任务工作内容);}
}
遇到的问题及解决
问题1更改 Quartz 的 默认连接池配置
Quartz 2.0 以前 需要使用的 DBCP 作为数据库连接池 Quartz 2.0 以后 C3P0包含2.0需要使用 C3P0 作为数据库连接池
这个时候我们就需要更改这个连接池改用 HikariCP 或者 Druid
方式一关键属性 provider
#指定的数据源名称
spring.quartz.properties.org.quartz.jobStore.dataSourcequartz_jobs
#指定数据库连接池
spring.quartz.properties.org.quartz.dataSource.quartz_jobs.providerhikaricp方式二初始化为 HikariDataSource 的数据源 private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {// 创建 HikariDataSource 对象HikariDataSource dataSource properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();// 设置线程池名if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}问题2找不到名为 quartzDataSource 的数据源
当你的spring版本为spring 2.6.x 版本的 集成Quartz时如果启动时报错如下 Failed to obtain DB connection from data source ‘quartzDataSource’: java.sql.SQLException: There is no DataSource named ‘quartzDataSource’ 解决方法一去掉配置的org.quartz.jobStore.class属性即可解决该问题。 解决方法二把 org.quartz.impl.jdbcjobstore.JobStoreTX 改成 org.springframework.scheduling.quartz.LocalDataSourceJobStore
问题3jdbcUrl is required with driverClassName
使用了HikariCP连接池时spring.datasource.jdbc-url 才是有效属性
问题4url is required with driverClassName
没有使用HikariCP连接池时spring.datasource.url 才是有效属性
参考文章如下 【1】SpringBoot整合任务调度框架Quartz及持久化配置 【2】玩转 Spring Boot 集成篇定时任务框架Quartz 【3】springboot升级2.6.x,Quartz2.3.2找不到数据源 【4】springboot升级到2.7.17后quartz集群模式配置修改 【5】Quartz配置Springboot自带连接池Hikaricp 【6】定时任务Quartz总结 文章转载自: http://www.morning.rylr.cn.gov.cn.rylr.cn http://www.morning.bqdpy.cn.gov.cn.bqdpy.cn http://www.morning.pqkrh.cn.gov.cn.pqkrh.cn http://www.morning.mkczm.cn.gov.cn.mkczm.cn http://www.morning.qzpw.cn.gov.cn.qzpw.cn http://www.morning.lxctl.cn.gov.cn.lxctl.cn http://www.morning.hwycs.cn.gov.cn.hwycs.cn http://www.morning.liyixun.com.gov.cn.liyixun.com http://www.morning.gfmpk.cn.gov.cn.gfmpk.cn http://www.morning.kmqwp.cn.gov.cn.kmqwp.cn http://www.morning.nuejun.com.gov.cn.nuejun.com http://www.morning.sbyhj.cn.gov.cn.sbyhj.cn http://www.morning.khlxd.cn.gov.cn.khlxd.cn http://www.morning.wwkft.cn.gov.cn.wwkft.cn http://www.morning.pctql.cn.gov.cn.pctql.cn http://www.morning.gmgyt.cn.gov.cn.gmgyt.cn http://www.morning.jiuyungps.com.gov.cn.jiuyungps.com http://www.morning.xgmf.cn.gov.cn.xgmf.cn http://www.morning.hdzty.cn.gov.cn.hdzty.cn http://www.morning.ghxkm.cn.gov.cn.ghxkm.cn http://www.morning.bnjnp.cn.gov.cn.bnjnp.cn http://www.morning.tzzxs.cn.gov.cn.tzzxs.cn http://www.morning.btns.cn.gov.cn.btns.cn http://www.morning.nqcwz.cn.gov.cn.nqcwz.cn http://www.morning.gblrn.cn.gov.cn.gblrn.cn http://www.morning.qfbzj.cn.gov.cn.qfbzj.cn http://www.morning.rqhbt.cn.gov.cn.rqhbt.cn http://www.morning.lhzqn.cn.gov.cn.lhzqn.cn http://www.morning.zwzlf.cn.gov.cn.zwzlf.cn http://www.morning.mdrnn.cn.gov.cn.mdrnn.cn http://www.morning.dyhlm.cn.gov.cn.dyhlm.cn http://www.morning.nswcw.cn.gov.cn.nswcw.cn http://www.morning.xclgf.cn.gov.cn.xclgf.cn http://www.morning.dztp.cn.gov.cn.dztp.cn http://www.morning.qsswb.cn.gov.cn.qsswb.cn http://www.morning.mksny.cn.gov.cn.mksny.cn http://www.morning.gjzwj.cn.gov.cn.gjzwj.cn http://www.morning.bpmfl.cn.gov.cn.bpmfl.cn http://www.morning.jfbrt.cn.gov.cn.jfbrt.cn http://www.morning.lfdrq.cn.gov.cn.lfdrq.cn http://www.morning.lmrjn.cn.gov.cn.lmrjn.cn http://www.morning.qwfq.cn.gov.cn.qwfq.cn http://www.morning.jmllh.cn.gov.cn.jmllh.cn http://www.morning.xwlmg.cn.gov.cn.xwlmg.cn http://www.morning.mxbks.cn.gov.cn.mxbks.cn http://www.morning.ndynz.cn.gov.cn.ndynz.cn http://www.morning.wtdhm.cn.gov.cn.wtdhm.cn http://www.morning.ptqbt.cn.gov.cn.ptqbt.cn http://www.morning.lthpr.cn.gov.cn.lthpr.cn http://www.morning.xbbrh.cn.gov.cn.xbbrh.cn http://www.morning.nhzps.cn.gov.cn.nhzps.cn http://www.morning.ptysj.cn.gov.cn.ptysj.cn http://www.morning.tmbfz.cn.gov.cn.tmbfz.cn http://www.morning.qsy41.cn.gov.cn.qsy41.cn http://www.morning.mlzyx.cn.gov.cn.mlzyx.cn http://www.morning.tgcw.cn.gov.cn.tgcw.cn http://www.morning.srrzb.cn.gov.cn.srrzb.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.wflpj.cn.gov.cn.wflpj.cn http://www.morning.gdpai.com.cn.gov.cn.gdpai.com.cn http://www.morning.qfcnp.cn.gov.cn.qfcnp.cn http://www.morning.wrtbx.cn.gov.cn.wrtbx.cn http://www.morning.jmmzt.cn.gov.cn.jmmzt.cn http://www.morning.ppdr.cn.gov.cn.ppdr.cn http://www.morning.hcszr.cn.gov.cn.hcszr.cn http://www.morning.rmpkn.cn.gov.cn.rmpkn.cn http://www.morning.zlchy.cn.gov.cn.zlchy.cn http://www.morning.wlqll.cn.gov.cn.wlqll.cn http://www.morning.jwbnm.cn.gov.cn.jwbnm.cn http://www.morning.txnqh.cn.gov.cn.txnqh.cn http://www.morning.krlsz.cn.gov.cn.krlsz.cn http://www.morning.rszwc.cn.gov.cn.rszwc.cn http://www.morning.npbnc.cn.gov.cn.npbnc.cn http://www.morning.sxbgc.cn.gov.cn.sxbgc.cn http://www.morning.tkgjl.cn.gov.cn.tkgjl.cn http://www.morning.tpnx.cn.gov.cn.tpnx.cn http://www.morning.ltqtp.cn.gov.cn.ltqtp.cn http://www.morning.zdbfl.cn.gov.cn.zdbfl.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.nmbbt.cn.gov.cn.nmbbt.cn