quartz简介
Quartz是OpenSymphony
开源组织在Job scheduling
领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer
。但是相较于Timer, Quartz增加了很多功能:
-
持久性作业 - 就是保持调度定时的状态;
-
作业管理 - 对调度作业进行有效的管理;
官方文档:
-
http://www.quartz-scheduler.org/documentation/
-
http://www.quartz-scheduler.org/api/2.3.0/index.html
quartz的使用
非Spring环境
引入
<!-- 核心包 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<!-- 工具包 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
编码
1、新建一个任务,实现 org.quartz.Job
接口:
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("任务被执行了。。。");
}
}
2、创建调度器、jobDetail 实例、trigger 实例、执行
public static void main(String[] args) throws Exception {
// 1.创建调度器 Scheduler
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
// 2.创建JobDetail实例,并与MyJob类绑定(Job执行内容)
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1")
.build();
// 3.构建Trigger实例,每隔30s执行一次
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
//设置跑在哪个scheduler上,频率是什么
.withSchedule(simpleSchedule()
.withIntervalInSeconds(30)
.repeatForever())
.build();
// 4.执行,开启调度器
scheduler.scheduleJob(job, trigger);
System.out.println(System.currentTimeMillis());
scheduler.start();
//主线程睡眠1分钟,然后关闭调度器
TimeUnit.MINUTES.sleep(1);
scheduler.shutdown();
System.out.println(System.currentTimeMillis());
}
与Spring boot集成
引入
<!-- Quartz 任务调度 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
默认在spring-boot-autoconfigure
jar包中已自动配置。包 org.springframework.boot.autoconfigure.quartz
。
编码
同上。
其他说明
Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行, 如果定时任执行太长,会长时间占用资源,导致其它任务堵塞。
@DisallowConcurrentExecution
禁止并发执行多个相同定义的JobDetail, 这个注解是加在Job类上的, 但意思并不是不能同时执行多个Job, 而是不能并发执行同一个Job Definition
(由JobDetail定义), 但是可以同时执行多个不同的JobDetail。
@PersistJobDataAfterExecution
同样, 也是加在Job上。表示当正常执行完Job后, JobDataMap中的数据应该被改动, 以被下一次调用时用。
当使用 @PersistJobDataAfterExecution
注解时, 为了避免并发时, 存储数据造成混乱, 强烈建议把 @DisallowConcurrentExecution
注解也加上。
阻止特定时间运行
//2014-8-15这一天不执行任何任务
Calendar c = new GregorianCalendar(2014, 7, 15);
cal.setDayExcluded(c, true);
scheduler.addCalendar("exclude", cal, false, false);
核心类介绍
Quartz 的核心类有以下三部分:
- 任务 Job : 需要实现的任务类,实现
execute()
方法,执行后完成任务。 - 触发器 Trigger : 包括
SimpleTrigger
和CronTrigger
。 - 调度器 Scheduler : 任务调度器,负责基于
Trigger
触发器,来执行 Job任务
JobDetail
JobDetail 的作用是绑定 Job,是一个任务实例,它为 Job 添加了许多扩展参数。
每次Scheduler
调度执行一个Job的时候,首先会拿到对应的Job的类,然后创建该Job实例,再去执行Job中的execute()
的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
JobDetail 就是一个Job实例的包装类。Sheduler每次执行,都会根据新的Job实例,这样就可以 规避并发访问 的问题。
JobExecutionContext
- 当
Scheduler
调用一个 job,就会将JobExecutionContext
传递给 Job 的execute()
方法; - Job 能通过
JobExecutionContext
对象访问到 Quartz 运行时候的环境以及 Job 本身的明细数据。
JobDataMap
有状态的 job 可以理解为多次 job调用期间可以持有一些状态信息,这些状态信息存储在 JobDataMap
中。
而默认的无状态 job,每次调用时都会创建一个新的 JobDataMap
。
让Job支持有状态,则需要在Job类上加注解
@PersistJobDataAfterExecution
Trigger
Trigger
可以设置任务的开始结束时间, Scheduler
会根据参数进行触发。
Calendar
一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。例如:每周星期一早上10:00执行任务,但是如果碰到法定的节日,则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。
public interface Calendar extends java.io.Serializable, java.lang.Cloneable {
int MONTH = 0;
void setBaseCalendar(Calendar baseCalendar);
Calendar getBaseCalendar();
boolean isTimeIncluded(long timeStamp);
//获取给定时间之后的下一个include 时间。
long getNextIncludedTime(long timeStamp);
String getDescription();
void setDescription(String description);
Object clone();
}
Calendar 名称 | 用法 | 精度 |
---|---|---|
BaseCalendar | 为高级的 Calendar 实现了基本的功能,实现了 org.quartz.Calendar 接口 | |
AnnualCalendar | 指定年中一天或多天。忽略年份。 | 天 |
CronCalendar | 指定CronExpression表达的时间集合。 | 秒 |
DailyCalendar | 每个DailyCalendar仅允许指定单个时间范围,并且该时间范围可能不会跨越每日边界(即,您不能指定从上午8点至凌晨5点的时间范围)。 如果属性invertTimeRange为false(默认),则时间范围定义触发器不允许触发的时间范围。 如果invertTimeRange为true,则时间范围被反转 - 也就是排除在定义的时间范围之外的所有时间。 | 毫秒 |
HolidayCalendar | 从 Trigger 中排除/包含节假日 | 天 |
MonthlyCalendar | 排除/包含月份中的指定数天 | 天 |
WeeklyCalendar | 排除/包含星期中的任意周几 | 天 |
源码解析
配置
QuartzAutoConfiguration
quartz在Spring boot 中 通过 在spring-boot-autoconfigure
jar中的包 org.springframework.boot.autoconfigure.quartz
下的 QuartzAutoConfiguration
类进行配置。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class })
@EnableConfigurationProperties(QuartzProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
LiquibaseAutoConfiguration.class, FlywayAutoConfiguration.class })
public class QuartzAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SchedulerFactoryBean quartzScheduler(QuartzProperties properties,
ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, ObjectProvider<JobDetail> jobDetails,
Map<String, Calendar> calendars, ObjectProvider<Trigger> triggers, ApplicationContext applicationContext) {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
SpringBeanJobFactory jobFactory = new SpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
schedulerFactoryBean.setJobFactory(jobFactory);
if (properties.getSchedulerName() != null) {
schedulerFactoryBean.setSchedulerName(properties.getSchedulerName());
}
schedulerFactoryBean.setAutoStartup(properties.isAutoStartup());
schedulerFactoryBean.setStartupDelay((int) properties.getStartupDelay().getSeconds());
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(properties.isWaitForJobsToCompleteOnShutdown());
schedulerFactoryBean.setOverwriteExistingJobs(properties.isOverwriteExistingJobs());
if (!properties.getProperties().isEmpty()) {
schedulerFactoryBean.setQuartzProperties(asProperties(properties.getProperties()));
}
schedulerFactoryBean.setJobDetails(jobDetails.orderedStream().toArray(JobDetail[]::new));
schedulerFactoryBean.setCalendars(calendars);
schedulerFactoryBean.setTriggers(triggers.orderedStream().toArray(Trigger[]::new));
customizers.orderedStream().forEach((customizer) -> customizer.customize(schedulerFactoryBean));
return schedulerFactoryBean;
}
private Properties asProperties(Map<String, String> source) {
Properties properties = new Properties();
properties.putAll(source);
return properties;
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnSingleCandidate(DataSource.class)
@ConditionalOnProperty(prefix = "spring.quartz", name = "job-store-type", havingValue = "jdbc")
protected static class JdbcStoreTypeConfiguration {
@Bean
@Order(0)
public SchedulerFactoryBeanCustomizer dataSourceCustomizer(QuartzProperties properties, DataSource dataSource,
@QuartzDataSource ObjectProvider<DataSource> quartzDataSource,
ObjectProvider<PlatformTransactionManager> transactionManager) {
return (schedulerFactoryBean) -> {
DataSource dataSourceToUse = getDataSource(dataSource, quartzDataSource);
schedulerFactoryBean.setDataSource(dataSourceToUse);
PlatformTransactionManager txManager = transactionManager.getIfUnique();
if (txManager != null) {
schedulerFactoryBean.setTransactionManager(txManager);
}
};
}
private DataSource getDataSource(DataSource dataSource, ObjectProvider<DataSource> quartzDataSource) {
DataSource dataSourceIfAvailable = quartzDataSource.getIfAvailable();
return (dataSourceIfAvailable != null) ? dataSourceIfAvailable : dataSource;
}
@Bean
@ConditionalOnMissingBean
public QuartzDataSourceInitializer quartzDataSourceInitializer(DataSource dataSource,
@QuartzDataSource ObjectProvider<DataSource> quartzDataSource, ResourceLoader resourceLoader,
QuartzProperties properties) {
DataSource dataSourceToUse = getDataSource(dataSource, quartzDataSource);
return new QuartzDataSourceInitializer(dataSourceToUse, resourceLoader, properties);
}
/**
* Additional configuration to ensure that {@link SchedulerFactoryBean} and
* {@link Scheduler} beans depend on any beans that perform data source
* initialization.
*/
@Configuration(proxyBeanMethods = false)
static class QuartzSchedulerDependencyConfiguration {
@Bean
static SchedulerDependsOnBeanFactoryPostProcessor quartzSchedulerDataSourceInitializerDependsOnBeanFactoryPostProcessor() {
return new SchedulerDependsOnBeanFactoryPostProcessor(QuartzDataSourceInitializer.class);
}
@Bean
@ConditionalOnBean(FlywayMigrationInitializer.class)
static SchedulerDependsOnBeanFactoryPostProcessor quartzSchedulerFlywayDependsOnBeanFactoryPostProcessor() {
return new SchedulerDependsOnBeanFactoryPostProcessor(FlywayMigrationInitializer.class);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(SpringLiquibase.class)
static class LiquibaseQuartzSchedulerDependencyConfiguration {
@Bean
@ConditionalOnBean(SpringLiquibase.class)
static SchedulerDependsOnBeanFactoryPostProcessor quartzSchedulerLiquibaseDependsOnBeanFactoryPostProcessor() {
return new SchedulerDependsOnBeanFactoryPostProcessor(SpringLiquibase.class);
}
}
}
}
/**
* {@link AbstractDependsOnBeanFactoryPostProcessor} for Quartz {@link Scheduler} and
* {@link SchedulerFactoryBean}.
*/
private static class SchedulerDependsOnBeanFactoryPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {
SchedulerDependsOnBeanFactoryPostProcessor(Class<?>... dependencyTypes) {
super(Scheduler.class, SchedulerFactoryBean.class, dependencyTypes);
}
}
}
在创建 SchedulerFactoryBean
时 ,会把设置JobDetails,Triggers。
SchedulerFactoryBean
可以通过 SchedulerFactoryBeanCustomizer
来设置属性。
@FunctionalInterface
public interface SchedulerFactoryBeanCustomizer {
/**
* Customize the {@link SchedulerFactoryBean}.
* @param schedulerFactoryBean the scheduler to customize
*/
void customize(SchedulerFactoryBean schedulerFactoryBean);
}
QuartzProperties
quartz 的 配置通过 spring.quartz
参数 配置。
quartz.properties里边的配置,都可以放到application.yml里的
spring. quartz.properties
下边
spring:
quartz:
properties:
org:
quartz:
threadPool:
threadCount: 10
threadPriority: 5
jobStore:
misfireThreshold: 50000
@ConfigurationProperties("spring.quartz")
public class QuartzProperties {
/**
* Quartz job store type.
*/
private JobStoreType jobStoreType = JobStoreType.MEMORY;
private String schedulerName;
private boolean autoStartup = true;
private Duration startupDelay = Duration.ofSeconds(0);
private boolean waitForJobsToCompleteOnShutdown = false;
private boolean overwriteExistingJobs = false;
/**
* spring. quartz.properties
*/
private final Map<String, String> properties = new HashMap<>();
private final Jdbc jdbc = new Jdbc();
}
加载配置过程
1、获取spring 配置
//QuartzAutoConfiguration.QuartzAutoConfiguration
if (!properties.getProperties().isEmpty()) {
schedulerFactoryBean.setQuartzProperties(asProperties(properties.getProperties()));
}
2、合并一些配置,并初始化
//SchedulerFactoryBean
private void initSchedulerFactory(StdSchedulerFactory schedulerFactory) throws SchedulerException, IOException {
Properties mergedProps = new Properties();
if (this.resourceLoader != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_SCHED_CLASS_LOAD_HELPER_CLASS,
ResourceLoaderClassLoadHelper.class.getName());
}
if (this.taskExecutor != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,
LocalTaskExecutorThreadPool.class.getName());
}
else {
// Set necessary default properties here, as Quartz will not apply
// its default configuration when explicitly given properties.
mergedProps.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, SimpleThreadPool.class.getName());
mergedProps.setProperty(PROP_THREAD_COUNT, Integer.toString(DEFAULT_THREAD_COUNT));
}
// 加载配置文件中的配置
if (this.configLocation != null) {
if (logger.isDebugEnabled()) {
logger.debug("Loading Quartz config from [" + this.configLocation + "]");
}
PropertiesLoaderUtils.fillProperties(mergedProps, this.configLocation);
}
//合并 配置
CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps);
if (this.dataSource != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
}
// Determine scheduler name across local settings and Quartz properties...
if (this.schedulerName != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, this.schedulerName);
}
else {
String nameProp = mergedProps.getProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME);
if (nameProp != null) {
this.schedulerName = nameProp;
}
else if (this.beanName != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, this.beanName);
this.schedulerName = this.beanName;
}
}
//初始化
schedulerFactory.initialize(mergedProps);
}
调度
quartz使用 SchedulerFactory
来实例化一个 调度器 。
SchedulerFactory
public interface SchedulerFactory {
Scheduler getScheduler() throws SchedulerException;
Scheduler getScheduler(String schedName) throws SchedulerException;
Collection<Scheduler> getAllSchedulers() throws SchedulerException;
}
quartz为SchedulerFactory
实现了2个实现类。
- StdSchedulerFactory:创建scheduler的标准工厂。
- DirectSchedulerFactory :直接创建scheduler的工厂,简单的单例实现,提供一些便捷方式。没有复杂的配置。
StdSchedulerFactory
创建scheduler的标准工厂。
通常是通过quartz.properties属性配置文件(默认情况下均使用该文件)结合StdSchedulerFactory 来使用Quartz的。StdSchedulerFactory 会加载属性配置文件并实例化一个Scheduler
DirectSchedulerFactory
Scheduler
Scheduler 维护了一个 JobDetails 和 Triggers 的注册表。
一旦在 Scheduler 注册过了,当定时任务触发时间一到,调度程序就会负责执行预先定义的 Job调度程序创建之后,处于 “ 待机 ” 状态,必须调用 scheduler 的 start() 方法启用调度程序可以使用 shutdown() 方法关闭调度程序,使用 isShutdown() 方法判断该调度程序是否已经处于关闭状态
通过 Scheduler.scheduleJob(…) 方法将任务纳入调度程序中,当任务触发时间到了的时候,该任务将被
执行
quartz的实现类如下:
public interface Scheduler {
//默认 Group:DEFAULT,用于Job,Trigger。
String DEFAULT_GROUP = Key.DEFAULT_GROUP;
String DEFAULT_RECOVERY_GROUP = "RECOVERING_JOBS";
/** 用于Trigger */
String DEFAULT_FAIL_OVER_GROUP = "FAILED_OVER_JOBS";
String FAILED_JOB_ORIGINAL_TRIGGER_NAME = "QRTZ_FAILED_JOB_ORIG_TRIGGER_NAME";
String FAILED_JOB_ORIGINAL_TRIGGER_GROUP = "QRTZ_FAILED_JOB_ORIG_TRIGGER_GROUP";
String FAILED_JOB_ORIGINAL_TRIGGER_FIRETIME_IN_MILLISECONDS = "QRTZ_FAILED_JOB_ORIG_TRIGGER_FIRETIME_IN_MILLISECONDS_AS_STRING";
String FAILED_JOB_ORIGINAL_TRIGGER_SCHEDULED_FIRETIME_IN_MILLISECONDS = "QRTZ_FAILED_JOB_ORIG_TRIGGER_SCHEDULED_FIRETIME_IN_MILLISECONDS_AS_STRING";
String getSchedulerName() throws SchedulerException;
String getSchedulerInstanceId() throws SchedulerException;
SchedulerContext getContext() throws SchedulerException;
/**
Scheduler 创建时的状态为:stand-by。不能执行触发器。必须启动之后。
*/
void start() throws SchedulerException;
/**
延迟多久启动
**/
void startDelayed(int seconds) throws SchedulerException;
boolean isStarted() throws SchedulerException;
/**
* 切回 stand-by 模式。
*/
void standby() throws SchedulerException;
boolean isInStandbyMode() throws SchedulerException;
/**
* 关闭 scheduler。不能再重新启动了。
* 等同 shutdown(false)
*/
void shutdown() throws SchedulerException;
/**
* @param waitForJobsToComplete,为true,表示一直阻塞 所有任务执行完成。
*/
void shutdown(boolean waitForJobsToComplete)
throws SchedulerException;
boolean isShutdown() throws SchedulerException;
SchedulerMetaData getMetaData() throws SchedulerException;
/** 获取所有正在执行的任务
*/
List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException;
void setJobFactory(JobFactory factory) throws SchedulerException;
ListenerManager getListenerManager() throws SchedulerException;
/**调度一个任务
*/
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
throws SchedulerException;
Date scheduleJob(Trigger trigger) throws SchedulerException;
void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) throws SchedulerException;
void scheduleJob(JobDetail jobDetail, Set<? extends Trigger> triggersForJob, boolean replace) throws SchedulerException;
/**取消调度 */
boolean unscheduleJob(TriggerKey triggerKey)
throws SchedulerException;
boolean unscheduleJobs(List<TriggerKey> triggerKeys)
throws SchedulerException;
Date rescheduleJob(TriggerKey triggerKey, Trigger newTrigger)
throws SchedulerException;
void addJob(JobDetail jobDetail, boolean replace)
throws SchedulerException;
void addJob(JobDetail jobDetail, boolean replace, boolean storeNonDurableWhileAwaitingScheduling)
throws SchedulerException;
boolean deleteJob(JobKey jobKey)
throws SchedulerException;
boolean deleteJobs(List<JobKey> jobKeys)
throws SchedulerException;
void triggerJob(JobKey jobKey)
throws SchedulerException;
void triggerJob(JobKey jobKey, JobDataMap data)
throws SchedulerException;
void pauseJob(JobKey jobKey)
throws SchedulerException;
void pauseJobs(GroupMatcher<JobKey> matcher) throws SchedulerException;
void pauseTrigger(TriggerKey triggerKey)
throws SchedulerException;
void pauseTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException;
void resumeJob(JobKey jobKey)
throws SchedulerException;
void resumeJobs(GroupMatcher<JobKey> matcher) throws SchedulerException;
void resumeTrigger(TriggerKey triggerKey)
throws SchedulerException;
void resumeTriggers(GroupMatcher<TriggerKey> matcher) throws SchedulerException;
void pauseAll() throws SchedulerException;
void resumeAll() throws SchedulerException;
List<String> getJobGroupNames() throws SchedulerException;
Set<JobKey> getJobKeys(GroupMatcher<JobKey> matcher) throws SchedulerException;
List<? extends Trigger> getTriggersOfJob(JobKey jobKey)
throws SchedulerException;
List<String> getTriggerGroupNames() throws SchedulerException;
Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> matcher) throws SchedulerException;
Set<String> getPausedTriggerGroups() throws SchedulerException;
JobDetail getJobDetail(JobKey jobKey)
throws SchedulerException;
Trigger getTrigger(TriggerKey triggerKey)
throws SchedulerException;
TriggerState getTriggerState(TriggerKey triggerKey)
throws SchedulerException;
void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
throws SchedulerException;
boolean deleteCalendar(String calName) throws SchedulerException;
Calendar getCalendar(String calName) throws SchedulerException;
List<String> getCalendarNames() throws SchedulerException;
boolean interrupt(JobKey jobKey) throws UnableToInterruptJobException;
boolean interrupt(String fireInstanceId) throws UnableToInterruptJobException;
boolean checkExists(JobKey jobKey) throws SchedulerException;
boolean checkExists(TriggerKey triggerKey) throws SchedulerException;
void clear() throws SchedulerException;
}
StdScheduler
标准Scheduler,主要功能是通过内部的 QuartzScheduler
实现。
附录
参考
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/cookbook/
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/
配置
主要配置
属性名称 | 必需 | 类型 | 默认值 |
---|---|---|---|
org.quartz.scheduler.instanceName | no | string | ‘QuartzScheduler’ |
org.quartz.scheduler.instanceId | no | string | ‘NON_CLUSTERED’ |
org.quartz.scheduler.instanceIdGenerator.class | no | string (class name) | org.quartz.simpl .SimpleInstanceIdGenerator |
org.quartz.scheduler.threadName | no | string | instanceName + ‘_QuartzSchedulerThread’ |
org.quartz.scheduler .makeSchedulerThreadDaemon | no | boolean | false |
org.quartz.scheduler .threadsInheritContextClassLoaderOfInitializer | no | boolean | false |
org.quartz.scheduler.idleWaitTime | no | long | 30000 |
org.quartz.scheduler.dbFailureRetryInterval | no | long | 15000 |
org.quartz.scheduler.classLoadHelper.class | no | string (class name) | org.quartz.simpl .CascadingClassLoadHelper |
org.quartz.scheduler.jobFactory.class | no | string (class name) | org.quartz.simpl.PropertySettingJobFactory |
org.quartz.context.key.SOME_KEY | no | string | none |
org.quartz.scheduler.userTransactionURL | no | string (url) | ‘java:comp/UserTransaction’ |
org.quartz.scheduler .wrapJobExecutionInUserTransaction | no | boolean | false |
org.quartz.scheduler.skipUpdateCheck | no | boolean | false |
org.quartz.scheduler .batchTriggerAcquisitionMaxCount | no | int | 1 |
org.quartz.scheduler .batchTriggerAcquisitionFireAheadTimeWindow | no | long | 0 |
- org.quartz.scheduler.instanceName:实例名称,用来区分特定的调度器实例。
- org.quartz.scheduler.instanceId:实例Id,用来区分特定的调度器实例。在集群模式下,必须保证唯一。是物理上唯一,instanceName是逻辑上的区分。假如想Quartz帮生成这个值的话,可以设置为AUTO。
- org.quartz.scheduler.instanceIdGenerator.class:调度器实例id的生成方式,只有在调度器示例id设置为Auto自动生成时有效。缺省值org.quartz.simpl.SimpleInstanceIdGenerator。
- org.quartz.scheduler.threadName:调度器的线程名称,默认使用instanceName+’_QuartzSchedulerThread’
- org.quartz.scheduler.makeSchedulerThreadDaemon:是否将schedule主线程设置为守护线程,默认false
- org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer:Quartz生成的线程是否继承初始化线程的上下文类加载器,默认false
- org.quartz.scheduler.idleWaitTime:在调度程序空闲时,重复查询是否有可用触发器的等待时间,默认30000(毫秒)
- org.quartz.scheduler.dbFailureRetryInterval:JobStore 模式下,连接超时重试连接的间隔,默认15000(毫秒)
- org.quartz.scheduler.classLoadHelper.class:类加载帮助类,默认org.quartz.simpl.CascadingClassLoadHelper
- org.quartz.scheduler.jobFactory.class:指定JobFactory的类(接口)名称,负责实例化jobClass,默认值为org.quartz.simpl.PropertySettingJobFactory
- org.quartz.context.key.SOME_KEY:代替 “scheduler context” 的一些配置。“org.quartz.context.key.MyKey = MyValue” 等价于
scheduler.getContext().put(“MyKey”, “MyValue”)
. 事务相关属性应该被排除在配置文件之外,除非使用的是JTA事务 - org.quartz.scheduler.userTransactionURL:设置Quartz能够加载UserTransaction的JNDI的 URL。
- org.quartz.scheduler.wrapJobExecutionInUserTransaction:是否在Quartz执行一个job前使用UserTransaction
- org.quartz.scheduler.skipUpdateCheck:在程序运行前检查quartz是否有版本更新,默认false
- org.quartz.scheduler.batchTriggerAcquisitionMaxCount:允许调度程序一次性触发的触发器数量,默认值1。1、值越大表示允许触发的任务越多;2、如果值大于1时,需要设置
org.quartz.jobStore.acquireTriggersWithinLock
属性为true,以避免多个触发器产生的数据混乱。 - org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow:允许触发器被获取并在其预定的触发时间之前触发的数量,默认数量为0
线程池配置
- org.quartz.threadPool.class:线程池的实现类,一般默认使用
org.quartz.simpl.SimpleThreadPool
(固定大小)实例。 - org.quartz.threadPool.threadCount:线程池中的线程数量,默认10。如果仅几个任务,建议1,如果上万个,建议50–100。
- org.quartz.threadPool.threadPriority:线程的优先级,默认5。最小优先级1,最高10。
- org.quartz.threadPool.makeThreadsDaemons:是否设置为守护线程,默认false。
- org.quartz.threadPool.threadsInheritGroupOfInitializingThread:加载任务的代码的ClassLoader是否从外部继承,默认true
- org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread:
- org.quartz.threadPool.threadNamePrefix:线程默认的前缀,默认Worker 。
如果是自定义的线程池,则可以设置自定义的属性值
org.quartz.threadPool.class = MyThreadPool org.quartz.threadPool.attr1 = someValue //MyThreadPool的属性attr1 的值 org.quartz.threadPool.attr2 = someValue //MyThreadPool的属性attr2 的值
RAMJobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.misfireThreshold:最大能忍受的触发超时时间,默认值60000(毫秒),超时则认为失误。
数据连接配置
quartz框架中数据源相关的配置属性的统一前缀为:org.quartz.jobStore.
-
class,job的存储方式,可以选择存储在内存中或者持久化数据库中,默认为null
- org.quartz.simpl.RAMJobStore 即存储在内存中,不适用配置文件时默认值
- org.quartz.impl.jdbcjobstore.JobStoreTX 表示选择JDBC存储方式,自己管理事务
- org.quartz.impl.jdbcjobstore.JobStoreCMT也表示JDBC,但是由全局JTA管理事务
-
driverDelegateClass,用于处理不同数据库之间差异的实现类,默认null
- 使用mysql jdbc数据存储时设置为为org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-
dataSource,配置数据源的名称,默认null
- 如果不配置数据源名称,可以使用spring配置文件中的数据源,并在scheduler创建时注入
- 如果此处配置了数据源的名称,可以进一步在quartz文件中配置数据源信息
# 配置数据源名称:`dataSoruce=dataSourceName` org.quartz.dataSource.dataSourceName.driver org.quartz.dataSource.dataSourceName.URL org.quartz.dataSource.dataSourceName.user org.quartz.dataSource.dataSourceName.password org.quartz.dataSource.dataSourceName.maxConnections
-
tablePrefix,表示quartz定时任务持久化时对应的数据表前缀,默认值
QRTZ_
-
misfireThreshold,最大能忍受的触发超时时间,默认值60000,超时则认为失误
-
useProperties,使用key-value的形式存储
JobDataMap
,默认true 指示JDBCJobStore所有的JobDataMaps中的值都是字符串,并且能以“名字-值”对的方式存储而不是以复杂对象的序列化形式存储在BLOB字段中,应该设置为true
-
isClustered,是否以集群方式运行,默认false
- 如果多个quartz实例使用同一个数据库,则需要设置为true,否则会报错
-
clusterCheckinInterval,检入到数据库中的频率,默认20000
-
maxMisfiresToHandleAtATime,JobStore处理未按时触发的Job数量,默认20
-
dontSetAutoCommitFalse,事务是否自动提交,默认false
-
selectWithLockSQL,配置加锁的SQL语句,默认false,需要配置时默认语句是:
SELECT * FROM [tableName] LOCKS WHERE LOCK_NAME = ? FOR UPDATE
- txIsolationLevelSerializable,是否使用事务隔离级别中的可序列化,默认false
- acquireTriggersWithinLock,触发事务前是否需要拥有锁,默认true
- lockHandler.class,用于管理数据库中相关锁机制的类名,默认null
Jdbc存储表结构
- qrtz_blob_triggers:以blob格式存放自定义trigger信息
- qrtz_calendars:记录quartz任务中的日历信息
- qrtz_cron_triggers:记录cronTrigger,即cron表达式相关触发器的信息
- qrtz_fired_triggers:存储正在触发的定时器的信息,执行完后数据清空
- qrtz_job_details:记录每个定时任务详细信息的表
- qrtz_locks:分布式处理时多个节点定时任务的锁信息
- qrtz_paused_triggers_grps:存储暂停的任务触发器信息
- qrtz_scheduler_state:记录调度器状态的表
- qrtz_simple_triggers:记录SimpleTrigger,即普通的触发器信息
- qrtz_simprop_triggers:存储CalendarIntervalTrigger和DailyTimeIntervalTrigger触发器信息
- qrtz_triggers:记录每个触发器详细信息的表