定时任务调度框架Quartz--SpringBoot使用Quartz并使用集群配置
基本配置
导入依赖
Quartz版本得话会跟着SpringBoot项目走
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
基本配置文件quartz.properties
不同节点之间的配置文件需要保持一致。
#----------------------------------------基础配置------------------------------------------------------------
org.quartz.scheduler.instanceName=QuartzScheduler
# 定时任务实例的id 默认自动
org.quartz.scheduler.instanceId=AUTO
# 是否是集群的任务
org.quartz.jobStore.isClustered=true
#--------------------------------------------------------------------------------------------------------
#----------------------------------------集成数据库置------------------------------------------------------------
# 定时任务的表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
# 使用数据库存储JOB数据
org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 保证待执行的任务是锁定的,持有锁超时,数据库会自动释放
org.quartz.jobStore.acquireTriggersWithinLock=true
# 检查集群的状态间隔
org.quartz.jobStore.clusterCheckinInterval=5000
# 如果当前的执行周期被错过 任务持有的时长超过此时长则认为任务过期,单位ms
org.quartz.jobStore.misfireThreshold=6000
# 事务的隔离级别 推荐使用默认级别 设置为true容易造成死锁和不可重复读的一些事务问题
org.quartz.jobStore.txIsolationLevelSerializable=false
#----------------------------------------------------------------------------------------------------
#----------------------------------------线程池配置------------------------------------------------------------
#可参考:https://www.w3cschool.cn/quartz_doc/quartz_doc-7vix2d9n.html
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 最多有10个定时任务同时执行
org.quartz.threadPool.threadCount=10
# 自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#----------------------------------------------------------------------------------------------------
官方提供的SQL语句
配置ScheduleFactoryBean与生成Job实例工厂
ScheduleFactoryBean主要用来拿到Quartz的核心:调度器Scheduler。
DataSouce就是系统启动的数据库连接资源,让Quartz知道你使用得是哪个数据库。
ScheduleJobFactory每次生成的都是一个Job接口的实现,也就是JobDetail实例对象。因此它不受Spring容器管理。
@Configuration
@RequiredArgsConstructor
public class QuartzScheduleConfiguration {
private final DataSource dataSource;
private final ScheduleJobFactory jobDetailInstanceFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
schedulerFactoryBean.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource("classpath:quartz.properties"));
schedulerFactoryBean.setDataSource(dataSource);
schedulerFactoryBean.setJobFactory(jobDetailInstanceFactory);
//schedulerFactoryBean.setGlobalJobListeners(); listeners do some log task
return schedulerFactoryBean;
}
}
@Configuration
@RequiredArgsConstructor
public class ScheduleJobFactory extends AdaptableJobFactory {
private final AutowireCapableBeanFactory beanFactory;
private final ApplicationContext applicationContext;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Class<?> jobClass = bundle.getJobDetail().getJobClass();
Constructor<?>[] constructors = jobClass.getDeclaredConstructors();
Class<?>[] cis = null;
Object[] constructorParams = null;
if (constructors.length > 0) {
if (constructors.length > 1) {
throw new SchedulerException("Job初始化异常,Job:"
+ jobClass.getName() + "只能配置一个构造器");
}
cis = constructors[0].getParameterTypes();
constructorParams = new Object[cis.length];
for (int i = 0; i < cis.length; i++) {
constructorParams[i] = applicationContext.getBean(cis[i]);
}
}
Object jobInstance;
if (cis != null && cis.length > 0) {
jobInstance = ReflectionUtils.accessibleConstructor(jobClass, cis).
newInstance(constructorParams);
} else {
jobInstance = ReflectionUtils.accessibleConstructor(jobClass).newInstance();
}
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
}