quartz使用及原理解析

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-schedulergroupId>
    <artifactId>quartzartifactId>
    <version>2.3.0version>
dependency>

<dependency>
    <groupId>org.quartz-schedulergroupId>
    <artifactId>quartz-jobsartifactId>
    <version>2.3.0version>
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集成

引入


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-quartzartifactId>
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 : 包括 SimpleTriggerCronTrigger
  • 调度器 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使用及原理解析_第1张图片

调度

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的实现类如下:

quartz使用及原理解析_第2张图片
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:记录每个触发器详细信息的表

你可能感兴趣的:(Java中间件,spring,spring,boot,quartz)