quartz.properties配置文件:
通常情况下,通过quartz.properties属性配置文件(默认使用该文件)结合StdSchedulerFactory来使用Quartz。
StdSchedulerFactory会加载属性配置文件并实例化一个Scheduler。
默认情况下,Quartz会加载classpath下的“quartz.properties”文件作为配置属性,如果找不到则会使用quartz框架自己jar下的ora/quartz包底下的“quartz.properties”文件。也可以手动指定“org.quartz.properties”属性指向自定义的配置文件。或者,可以在调用StdSchedulerFactory的getScheduler()方法之前调用initialize(xx)初始化factory配置。
在配置文件中可以使用“¥@”引用其他属性配置
Configure Main Scheduler Properties调度器属性:
在集群中每个实例都必须有一个唯一的instanceId,但是应该有一个相同的instanceName(默认 “QuartzScheduler”)
实例名(非必须):
org.quartz.scheduler.instanceName:可以定义为任何字符串,用来在用到多个调度器区分特定的调度器实例。多个调度器通常用在集群环境中。可以指定线程名,如果不指定的话,可以设置为org.quartz.shcheduler.instanceName:QuartzScheduler(也是没有该属性配置时的默认值)。
实例ID(非必须):
org.quartz.scheduler.instanceId。instanceId属性也允许任何字符串。这个值必须是在所有调度器实例中是唯一的。在一个集群当中,如果想让Quartz帮你生成这个值的话,可以设置为AUTO。如果Quartz框架是运行在非集群环境中,那么自动产生的值将会是NON_CLUSTERED。如果是在集群环境下使用Quartz,这个值将会是主机名加上当前的日期和时间。大多数情况下,设置为AUTO即可。只有在“org.quartz.sacheduler.instanceId”设置为AUTO的时候才使用该属性设置。默认情况下“org.quartz.simpl.SimpleInstanceIdGenerator”是基于instanceId和时间戳来自动生成的。其他的id生成器的实现包括SystemPropertyInstanceIdGenerator从系统属性获取“org.quartz.scheduler.instanceId”,和HostnameInstanceIdGenerator使用主机名(InetAddress.getLocalHost().getHostName())。也可以自定义生成方式(默认org.quartz.simpl.SimpleInstanceIdGeneratore)
指定scheduler的主线程是否为后台线程(非必须):
org.quartz.scheduler.makeSchedulerThreadDaemon = false (默认false)
指定Quartz生成的线程是否继承初始化线程的上下文类加载器(非必须):
这会影响Quartz的主调度线程、JDBCJobStore的熄火“处理线程、集群回复线程和线程池里的线程。将该值设置为”true“可以帮助类加载,JNDI查找,并在应用程序服务器上使用Quartz等相关问题。
org.quartz.scheduler.threadInheritContextClassLoaderOfInitializer = false(默认false)
在调度程序空闲的时候,重复查询是否有可用触发器的等待时间(非必须):
通常并不会设置为true,除非你使用XA事务(XA事务是基于两阶段提交协议实现的,可以保证数据的强一致性,许多分布式关系型数据管理系统都采用此协议来完成分布式。XA事务允许不同数据库分布式事务,只要参与在全局事务中的每个结点都支持XA事务。Oracle、Mysql、SQL Server都支持XA事务,XA事务由一个或多个资源管理器(RM,提供访问资源的方法,通常一个数据库就是一个资源管理器)、一个事务管理器(TM,协调参与全局事务中的各个事务。需要和参与全局事务的所有资源管理器进行通信)、一个应用程序(定义事务的边界),XA事务的缺点是性能不好,且无法满足高并发场景,一个数据库的事务和多个数据库间的XA事务性能会相差很多。因此要尽量避免XA事务,如可以将数据写入本地,用高性能的消息系统分发数据,或使用数据库复制等技术。只有在其他办法都无法实现业务需求,且性能不是瓶颈时才使用XA),并且延迟触发会导致问题的场景。5000ms以下是不推荐的,因为它会导致过多的数据库查询,1000ms以下是非法的。
org.quartz.scheduler.idleWaitTime = 30000 (默认30000)
连接超时重试连接的间隔(非必须):
使用RomJobStore时,该参数并没有什么用
org.quartz.scheduler.dbFailureRetryInterval = 15000 (默认15000)
最可靠的方式就是使用(org.quartz.simpl.CascadingClassLoadHelper),没必要指定其他类(非必须):
org.quartz.shceduler.classLoadHeler.class = org.quartz.simpl.CascadingClassLoadHelper
指定JobFactory的类(接口)名称。负责实例化jobClass(非必须):
默认org.quartz.simpl.PropertySettingJobFactory,只是在job被执行的时候简单调用newInstance()实例化一个job类。PropertySettingJobFactory会使用反射机制通过SchedulerContext、Job、Tigger和JobDataMaps设置job bean的属性。在使用JTA事务时可设置相关事务的属性。
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.PropertySettingJobFactory
org.quartz.context.key.SOME_KEY = none
设置Quartz能够加载UserTransaction的JNDI的URL(非必须):
Websphere的用户可能会设置为”jta/usertransaction“。只有在Quartz使用JobStoreCMT的时候,才会使用该属性,并且org.quartz.scheduler.wrapJobExceutionInUserTransaction也会设置为true,默认(”java
:comp/UserTransaction“)
org.quartz.scheduler.userTransactionURL = java:comp/UserTransaction
Quartz在执行一个job前使用User Transaction,则应设置该属性为true(非必须):
job执行完,在JobDataMap改变之后事务会提交,默认值是false,可以在你的job类中使用@ExecuteInJTATransaction注解,可以控制job是否使用事务
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false (默认false)
检查quartz是否有版本更新(非必须):
建议设置为true,这样就不会在程序运行中还去检查quartz是否有版本更新
org.quartz.scheduler.skipUpdateChexk = true (默认false)
允许调度程序一次性触发的触发器数量(非必须):
值越大一次性触发的任务就可以越多,但是在集群环境下,不建议设置为很大值。如果值 > 1 ,并且使用了JDBC JobStore的话,org.quartz.jobStore.acquireTriggersWithinLock属性必须设置为true,以避免”弄脏“数据。
org.quartz.scheduler.batchTriggerAcquisitionMaxCount = 1 (默认1)
允许触发器被获取并在其预定的触发时间之前触发的数量(非必须):
org.quartz.scheduler.batchTriggerAcquisitionFIreAheadTimeWindow = 0 (默认0)
Configure ThreadPool 线程池属性
线程池的实现类(定长线程池,几乎可满足所有用户的需求)(必须):
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool (默认null)
指定线程数,至少为1,一般设置为1-100直接的整数合适(必须):
org.quartz.thread.threadCount = 25 (无默认值)
设置线程的优先级(最大为java.lang.Thread.MAX_OPIORITY 10,最小为Thread.MIN_PRIORITY 1)(非必须):
org.quartz.threadPool.threadPriority = 5
设置Simple ThreadPool的一些属性,一般使用默认值
设置是否为守护线程:
org.quartz.threadPool.makethreadsdaemons = false
org.quartz.threadPool.threadInheritContextClassLoaderOfInitializingThread = true
org.quartz.threadPool.threadsinheritgroupoflnitializingthread = false
线程前缀默认值是:[Scheduler Name_Worker]
org.quartz.threadPool.threadnameprefix = swhJobThead;
配置全局监听(TiggerListener,JobListener)则应用程序可以接收和执行预定的事件通知
Configuring a Global TriggerListener配置全局Trigger监听器
Configure JobStore配置数据存储的方式
使用RAMJobStore配置
将schedule相关信息保存在RAM中,轻量级,速度快,遗憾的是应用重启时相关信息都将丢失。
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
最大能忍受的触发超时时间(触发器被认定为“misfired”之前),如果超时则认为“失误”
org.quartz.jobStore.misfireThreshold = 60000 (默认60秒)
使用JDBCJobStore配置
所有的quartz数据例如job和Trigger的细节信息被保存在内存或数据库中,有两种实现,JobStoreTX(自己管理事务)和JobStoreCMT(application server 管理事务,即全局事务JTA)
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
类似于Hibernate的dialect,用于处理DB之间的差异,StdJDBCDelegate能满足大部分的DB
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
配置数据源的名称,在后面配置数据源的时候要用到,例如org.quartz.dataSource.clusterDS.driver = com.mysql.jdbc.Driver
org.quartz.jobStore.dataSource = clusterDS
数据表前缀
org.quartz.jobStore.tablePrefix = QRTZ_
为了指示JDBCJobStore所有的JobDataMaps中的值都是字符串,并且能以“名字-值”对的方式存储而不是以复杂对象的序列化形式存储在BLOB字段中,应该设置为true(缺省方式)
org.quartz.jobStore.useProperties = true
是否集群、负载均衡、容错,如果应用在集群中设置为false会出错
org.quartz.jobStore.isClustered = true
检入到数据库中的频率(毫秒)。检查是否其他的实例到了应当检入的时候未检入这能指出一个失败的实例,且当前Scheduler会以此来接管执行失败并可回复的Job通过检入操作,Scheduler也会更新自身的状态记录
org.quartz.jobStore.clusterCheckinInterval = 20000
JobStore处理未按时触发的Job的数量
org.quartz.jobStore.maxMisfiresToHandleAtATime = 20
true/false,true则调用connection的setAutoCommit(false)方法
org.quartz.jobStore.dontSetAutoCommitFalse = true
加锁的sql语句,默认为SELECT * FROM{0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE #{0} = $@org.quartz.jobStore.tablePrefix
org.quartz.jobStore.selectWithLockSQL = false
true/false,true则调用connection的
setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)方法
org.quartz.jobStore.txIsolationLevelSerializable = false
触发job时是否需要拥有锁
org.quartz.jobStore.acquireTriggersWithinLock = true
用于管理数据库中相关信息的锁机制的类名
org.quartz.jobStore.lockHandler.class =
Configure Datasources数据源
使用常规数据源配置
数据库驱动:
org.quartz.dataSource.NAME.driver = com.mysql.jdbc.Driver
数据库连接地址:
org.quartz.dataSource.NAME.URL = jdbc:mysql://${mysql.address}/etc-quartz?useUnicode=true&characterEncoding= utf8
数据库用户名:
org.quartz.dataSource.NAME.user = #{mysql.user}
数据库密码:
org.quartz.dataSource.NAME.password = ${mysql.password}
数据库最大连接数(如果Scheduler很忙,比如执行的任务与线程池的数量差不多相同,那就需要配置DataSource的连接数量为线程池数量+1):
org.quartz.dataSource.NAME.maxConnections = 30
dataSource用于检测connection是否failed/corrupt的SQL语句:
org.quartz.dataSource.NAME.validationQuery = select RAND()
使用JNDI数据源配置
JNDI URL:
org.quartz.dataSource.NAME.jndiURL =
JNDI InitialContextFactory:
org.quartz.dataSource.NAME.java.naming.factory.initial =
以下为连接到JNDI提供者的相关信息:
org.quartz.dataSource.NAME.java.naming.provider.url =
org.quartz.dataSource.NAME.java.naming.security.principal =
org.quartz.dataSource.NAME.java.naming.security.credentials =
用户自定义org.quartz.utils.ConnectionProvider实现类
org.quartz.dataSource.NAME.connectionProvider.class =
org.quartz.dataSource.NAME.XXX =
实现故障处理和负载均衡,实现高可用性和扩展性通过共享DB Tables实现,所以必须使用JDBC-JobStore
负载均衡 : 谁先触发谁执行,并且一次只有一个scheduler触发
故障处理 : 当一个scheduler失败后,其它的实例可以发现那些执行失败的Jobs,假如Job对应的JobDetail标记为recovery(属性"requests recovery"),那么该Job就会被其它的实例重新执行,否则对应的Job只会被释放等待下次被触发。
实现:org.quartz.jobStore.isClustered = true
所有的实例的quartz.properties文件除了org.quartz.scheduler.instanceId和org.quartz.threadPool.threadCount必须一致,org.quartz.scheduler.instanceId = AUTO 即可实现ID的不一致
注意:
1、不在不同的机器上实现集群功能,除非他们的时钟同步精确到秒
2、不实现集群的实例不使用同一套表
Configure Plugins 插件配置
配置trigger执行历史日志(可以看到类的文档和参数列表):
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}
org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}
加载 Job 和 Trigger 信息的类 (1.8之前用:org.quartz.plugins.xml.JobInitializationPlugin)
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
指定存放调度器(Job 和 Trigger)信息的xml文件,默认是classpath下quartz_jobs.xml:
org.quartz.plugin.jobInitializer.fileNames = quartz_data.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
覆盖任务调度器中同名的jobDetail,避免只修改了CronExpression所造成的不能重新生效情况:
org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
自动扫描任务单并发现改动的时间间隔,单位为秒。设置为0表示不自动加载:
org.quartz.plugin.jobInitializer.scanInterval = 120
覆盖任务调度器中同名的jobDetail,避免只修改了CronExpression所造成的不能重新生效情况:
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
Sample configuration of ShutdownHookPlugin ShutdownHookPlugin插件的配置样例
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true
Configure RMI Settings 远程服务调用配置:
如果你想quartz-scheduler出口本身通过RMI作为服务器,然后设置“出口”标志true:
org.quartz.scheduler.rmi.export = false (默认false)
主机上rmi注册表:
org.quartz.scheduler.rmi.registryhost = localhost (默认localhost)
注册监听端口号:
org.quartz.scheduler.rmi.registryport = 1099(默认1099)
创建rmi注册,false/never:如果你已经有一个在运行或不想进行创建注册:
true/as_needed:第一次尝试使用现有的注册,然后再回来进行创建:
always:先进行创建一个注册,然后再使用回来使用注册:
org.quartz.scheduler.rmi.createregistry = never
Quartz Scheduler服务端端口,默认是随机分配RMI注册表:
org.quartz.scheduler.rmi.serverport = 1098
true:链接远程服务调度(客户端),这个也要指定registryhost和registryport,默认为false
如果export和proxy同时指定为true,则export的设置将被忽略
Configuring a Global TriggerListener 配置全局的Trigger监听器
MyTriggerListenerClass 类必须有一个无参数的构造函数,和属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串):
org.quartz.triggerListener.NAME.class = com.swh.MyTriggerListenerClass
org.quartz.triggerListener.NAME.propName = propValue
org.quartz.triggerListener.NAME.prop2Name = prop2Value
Configuring a Global JobListener 配置全局的Job监听器
MyJobListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串):
org.quartz.jobListener.NAME.class = com.swh.MyJobListenerClass
org.quartz.jobListener.NAME.propName = propValue
org.quartz.jobListener.NAME.prop2Name = prop2Value