0 前言
Quartz的配置通常是使用properties文件结合StdSchedulerFactory完成的。StdSchedulerFactory读取配置文件,并实例化scheduler。
默认情况下,StdSchedulerFactory从当前工作目录加载“quartz.properties”文件。如果加载失败,那么就会尝试加载org/quartz包下的“quartz.properties”文件。如果不想用默认的文件,你可以定义一个系统属性“org.quartz.properties”指向你想要的文件。
作为选择,在调用StdSchedulerFactory的getScheduler()方法之前,你可以明确的调用initialize(xx)方法实例化这个工厂。
JobStore、ThreadPool还有其它的SPI类的实例都根据名字创建,然后配置文件中的属性调用它们set方法来设置。例如,如果属性文件包含属性“org.quartz.jobStore.myProp = 10”,那么当JobStore类被实例化完成后,就会调用它的“setMyProp()”。在调用属性的setter方法之前会将类型转换为基本类型(int、long、float、double、boolean和String)。
一个属性可以引用另一个属性的值来指定值,遵循约定“$@other.property.name”。例如,其它的属性引用scheduler实例的名字作为值,你可以这样使用:“$@org.quartz.scheduler.instanceName”。
关于Scheduler不同方面的属性配置在接下来的各个章节介绍。
1 配置Scheduler的主要属性
这些属性配置Scheduler的标识以及其它顶级的设置。
属性名 |
必需 |
类型 |
默认值 |
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 |
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 |
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
可以是任意字符串,这个值对于scheduler自己来说没有任何意义,但是当多个实例存在同一个程序中时,它可以用于区分不同的scheduler。如果你使用集群特性,那么在集群中逻辑术语同一个scheduler的实例必须使用相同的名字。
org.quartz.scheduler.instanceId
可以是任意字符串,但是如果在集群中多个scheduler在逻辑上是同一个Scheduler,那么就必须是唯一的。如果将它的值设置为“AUTO”,它会自动为你生成Id。如果将它的值可以为“SYS_PROP”,它的值来自系统属性“org.quartz.scheduler.instanceId”。
org.quartz.scheduler.instanceIdGenerator.class
只有org.quartz.scheduler.instanceId设置为“AUTO”才使用。默认为“org.quartz.simpl.SimpleInstanceIdGenerator”,它是主机名和时间戳生成实例Id的。其它的IntanceIdGenerator实现包括SystemPropertyInstanceIdGenerator(它从系统属性“org.quartz.scheduler.instanceId”获取实例Id),和HostnameInstanceIdGenerator(它使用本地主机名InetAddress.getLocalHost().getHostName()生成实例Id)。你也实现你自己的InstanceIdGenerator。
org.quartz.scheduler.threadName
可以任意合法的线程名。如果这个属性没有设置,那么线程就会用Scheduler的名字(“org.quartz.scheduler.instanceName”)加上字符串“_QuartzSchedulerThread”。
org.quartz.scheduler.makeSchedulerThreadDaemon
布尔值(true或者false),表明scheduler的主线程是否为守护线程。如果你使用的是SimpleThreadPool(大部分情况都是用的这个),请参见它的org.quartz.scheduler.makeSchedulerThreadDaemon属性。
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer
A布尔值(true或者false),表明Quartz产生的线程是否继承初始化Quartz实例的线程的上下文类加载器。这会影响Quartz主调度线程,JDBCJobStore的失败处理线程(使用JDBCJobStore的话),还有SimpleThreadPool中的线程(如果使用SimpleThreadPool的话)。将这个值设置为true,对于类加载、JNDI查找以及其它在应用服务器内使用Quartz的问题有所帮助。
org.quartz.scheduler.idleWaitTime
当scheduler空闲时,scheduler重新查询可用的trigger等待的时间(单位毫秒)。通常你不需要调整这个参数,除非你使用XA事务,并且不应该延迟触发trigger会而应该立即触发。不推荐小于5000ms,因为它会造成大量的数据库查询。小于1000是不合法的。
org.quartz.scheduler.dbFailureRetryInterval
当检测到失去与JobStore(或数据库)的连接时,scheduler重连的等待时间(单位毫秒)。当使用RamJobStore时,该参数没有意义。
org.quartz.scheduler.classLoadHelper.class
默认为最稳定的方法,就是使用“org.quartz.simpl.CascadingClassLoadHelper”类,它会使用其它的ClassLoadHelper类,直到有一个工作。你可能会发现不需要设置这个属性,尽管在应用服务器内会有奇怪的事情发生。所有当前实现的ClassLoadHelper都位于org.quartz.simpl包下。
org.quartz.scheduler.jobFactory.class
使用的JobFactory的类名。JobFatcory负责生成Job实例。默认值为“org.quartz.simpl.PropertySettingJobFactory”,它简单的调用Job类的newInstance()方法来生成实例。PropertySettingJobFactory也分别用SchedulerContext、Job还有Trigger的JobDataMap设置Job的属性。
org.quartz.context.key.SOME_KEY
表示名字-值对,它会作为字符串放入SchedulerContext中(参见Scheduler.getContext())。例如,“org.quartz.context.key.MyKey = MyValue”会等价于执行scheduler.getContext().put(“MyKey”, “MyValue”)。
注意:与事务有关的属性可以不用设置,除非你使用JTA事务。
org.quartz.scheduler.userTransactionURL
设置为JNDI的URL,Quartz基于此定位应用服务器的UserTransaction管理者。默认值为“java:comp/UserTransaction”,这适用于大多数应用服务器。Websphere用户需要将它设置为“jta/usertransaction”。只有使用JobStoreCMT且org.quartz.scheduler.wrapJobExecutionInUserTransaction为true时,才需要配置这个属性。
org.quartz.scheduler.wrapJobExecutionInUserTransaction
如果你想要在执行Job之前启动一个UserTransaction,那么这个值就需要设置true。在Job执行完成且JobDataMap更新完成(有状态Job)之后,事务就会条提交。默认值为false。你也可能对在Job类上使用@ExecuteInJTATransaction 注解感兴趣,对于单个Job来说,它能让你控制Quartz是否应该启动一个JTA事务,这个属性对所有Job都有效。
org.quartz.scheduler.skipUpdateCheck
是否跳过快速访问web请求,以确定是否需要下载Quartz的更新版本。如果执行检查,且找到了更新,它会在Quartz日志中报告更新可用。你可以禁止更新检查,只需设置系统属性“org.terracotta.quartz.skipUpdateCheck=true”,在命名行用-D参数指定。在生产环境部署时,建议禁止更新检查。
org.quartz.scheduler.batchTriggerAcquisitionMaxCount
Scheduler一次获取trigger的最大数量。默认值为1。这个数字越大,触发效率越高(在有许多trigger需要同时触发的场景下),但是在集群节点之间可能会有负载均衡的代价。如果这个属性的值大于1,且使用JDBCJobStore,那么属性“org.quartz.jobStore.acquireTriggersWithinLock”必须设置true,以避免数据损坏。
org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow
允许triger在调度时间之前获取和触发的时间(单位毫秒)。默认0。这个数字越大,批量获取要触发的trigger且在同一时刻触发一个以上的trigger的可能性越大,但是以不精确调度为代价的(triggers可能提前触发)。这对于那些Scheduler有大量的trigger需要几乎同时触发的场景是很有用的(一般是性能测试)。
2 配置线程池
属性名 |
必需 |
类型 |
默认值 |
org.quartz.threadPool.class |
yes |
string (类名) |
null |
org.quartz.threadPool.threadCount |
yes |
int |
-1 |
org.quartz.threadPool.threadPriority |
no |
int |
Thread.NORM_PRIORITY (5) |
org.quartz.threadPool.class
使用ThreadPool的实现的名字。Quartz自带的线程池是“org.quartz.simpl.SimpleThreadPool”,几乎满足所有用户的需求。它的行为很简单,测试的也很好。它提供了固定大小的线程池,生命周期与Scheduler相同。
org.quartz.threadPool.threadCount
可以是任意的正整数。实际上只有1到100会用到。这是并行执行job可用的线程数。如果只有几个job,一天也只有几次触发,那么一个线程就足够了!如果你有成百上千的job,且每一个每一分钟都会触发。那么你可能想要让线程的数量达到50或者100了(这取决于你的job执行的工作以及系统资源了)。
org.quartz.threadPool.threadPriority
可以是Thread.MIN_PRIORITY (1)和Thread.MAX_PRIORITY (10)之间的任意整数。默认为Thread.NORM_PRIORITY (5).
2.1 SimpleThreadPool的特定属性
属性名 |
必需 |
类型 |
默认值 |
org.quartz.threadPool.makeThreadsDaemons |
no |
boolean |
false |
org.quartz.threadPool.threadsInheritGroupOfInitializingThread |
no |
boolean |
true |
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread |
no |
boolean |
false |
org.quartz.threadPool.threadNamePrefix |
no |
string |
[Scheduler Name]_Worker |
org.quartz.threadPool.makeThreadsDaemons
可以设为true,那么线程池中创建的线程都是守护线程。默认为false。也可参见org.quartz.scheduler.makeSchedulerThreadDaemon属性。
org.quartz.threadPool.threadsInheritGroupOfInitializingThread
可以为true或者false,默认为false。
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread
可以为true或者false,默认为false。
org.quartz.threadPool.threadNamePrefix
线程池中线程名字的前缀,最后附加一个数字。
2.2 自定义的ThreadPool
如果你使用的自己实现的线程池,你可以将属性名按下面这样命名:
设置自定义ThreadPool的属性
org.quartz.threadPool.class = com.mycompany.goo.FooThreadPool
org.quartz.threadPool.somePropOfFooThreadPool = someValue
3 配置全局的监听器
全局的监听器可以由StdSchedulerFactory实例化和配置,或者由你的应用自己在运行时配置,然后将监听器注册到scheduler中。全局的监听器监听每一个job或trigger的事件,而不只是直接引用它的job和trigger。
通过配置文件配置监听器主要包括指定一个名字,然后指定类名,以及其它需要设置的属性。这个类必须有一个无参数构造器,且属性时分别设置的。只支持基本数据类型(包括String)。
全局TriggerListener的通用模式定义:
配置全局的TriggerListener
org.quartz.triggerListener.NAME.class = com.foo.MyListenerClass
org.quartz.triggerListener.NAME.propName = propValue
org.quartz.triggerListener.NAME.prop2Name = prop2Value
全局JobListener的通用模式定义:
配置全局的JobListener
org.quartz.jobListener.NAME.class = com.foo.MyListenerClass
org.quartz.jobListener.NAME.propName = propValue
org.quartz.jobListener.NAME.prop2Name = prop2Value
4 配置Scheduler插件
类似于监听器,配置插件也是通过配置文件,主要包括指定一个名字,然后指定类名,以及其它需要设置的属性。这个类必须有一个无参数构造器,且属性时分别设置的。只支持基本数据类型(包括String)。
这样,配置插件的通用模式如下:
配置一个插件
org.quartz.plugin.NAME.class = com.foo.MyPluginClass
org.quartz.plugin.NAME.propName = propValue
org.quartz.plugin.NAME.prop2Name = prop2Value
Quartz自带了几个插件,可以在org.quartz.plugins包(或子包)下找到。配置示例如下。
4.1 LoggingTriggerHistoryPlugin配置示例
LoggingTriggerHistoryPlugin会捕获triger事件(因为它也是一个TriggerListener),然后用Jakarta Commons-Logging记录到日志中。可以参见JavaDoc了解它的参数。
LoggingTriggerHistoryPlugin配置示例
org.quartz.plugin.triggHistory.class = \
org.quartz.plugins.history.LoggingTriggerHistoryPlugin
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\}.
4.2 XMLSchedulingDataProcessorPlugin配置示例
这是一个Job初始化插件,它从XML文件中读取job和trigger,并将它们添加到scheduler中。它也可以删除已有的数据。参见这个类的JavaDoc了解更多信细节。
Job初始化插件配置示例
org.quartz.plugin.jobInitializer.class = \
org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = \
data/my_job_data.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
XML schema定义是http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd
4.3 ShutdownHookPlugin配置示例
ShutdownHookPlugin捕获JVN终止的事件,并调用scheduler的shutdown方法。
ShutdownHookPlugin配置示例
org.quartz.plugin.shutdownhook.class = \
org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true
5 配置RMI
没有基本属性是必需的,都有默认值。当通过RMI访问Quartz时,你需要启动一个Quartz实例,它通过RMI导出了服务。然后你创建一个客户端,配置Quartz scheduler来代理服务器上的工作。
一些用户可能会在客户端和服务端遇到类可用性问题(即Job类)。要解决这些问题,你需要理解RMI的基础代码和安全管理。你会发现下面这些资源是有用的:
RMI和基础代码介绍:http://www.kedwards.com/jini/codebase.html。重点之一就是要由客户端实现基础代码。
安全管理快速入门:http://gethelp.devx.com/techtips/java_pro/10MinuteSolutions/10min0500.asp
最后,从Java API文档,阅读RMISecurityManager稳定。
属性名 |
必需 |
默认值 |
org.quartz.scheduler.rmi.export |
no |
false |
org.quartz.scheduler.rmi.registryHost |
no |
'localhost' |
org.quartz.scheduler.rmi.registryPort |
no |
1099 |
org.quartz.scheduler.rmi.createRegistry |
no |
'never' |
org.quartz.scheduler.rmi.serverPort |
no |
random |
org.quartz.scheduler.rmi.proxy |
no |
false |
org.quartz.scheduler.rmi.export
如果你想要让Quartz Scheduler通过RMI导出,那么需要将rmi.export标志为true。
org.quartz.scheduler.rmi.registryHost
可以找到RMI注册表的主机(通常为localhost)。
org.quartz.scheduler.rmi.registryPort
RMI注册表监听的端口(通常为1099)。
org.quartz.scheduler.rmi.createRegistry
根据你想要Quartz如何创建RMI注册表,来设置rmi.createRegistry标志。如果你不想让Quartz创建注册表(已经有一个外部的注册表在运行),那么就用false或never。如果你想要让Quartz第一次尝试使用已有的注册表,然后创建一个,就设置为true或则as_needed。如果你想要Quartz尝试创建一个注册表,然后使用它,那么就设置为always。如果已经创建了,它会绑定到org.quartz.scheduler.rmi.registryPort指定的端口上,org.quartz.rmi.registryHost应该为localhost。
org.quartz.scheduler.rmi.serverPort
Quartz Scheduler服务绑定和监听连接的端口。默认情况下,RMI服务会随机选择一个端口将scheduler绑定到RMI注册表。
org.quartz.scheduler.rmi.proxy
如果你想要连接到远端提供服务的scheduler,那么将org.quartz.scheduler.rmi.proxy标志设置为true。你也必须为RMI注册表指定一个主机和端口,通常为localhost和1099。
注意,在同一个配置文件中,将org.quartz.scheduler.rmi.export和org.quartz.scheduler.rmi.proxy都设置为true是没有意义的。如果你这样做了,那么export选项就会被忽略。如果export和proxy属性都是false当然是合法的,如果你不使用RMI的话。
6 配置RAMJobStore
RAMJobStore用于在内存里存储调度信息(job、triggers和calendar)。RAMJobStore 快速且轻量,但是当进程终止时所有调度信息会丢失。
选择RAMJobStore的话,需要这样设置org.quartz.jobStore.class属性:
设置Scheduler的JobStore为RAMJobStore
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
RAMJobStore可以调整以下参数:
属性名 |
必须 |
类型 |
默认值 |
org.quartz.jobStore.misfireThreshold |
no |
int |
60000 |
org.quartz.jobStore.misfireThreshold
trigger被认为失败之前,scheduler能够承受的下一次触发时间(单位毫秒)。默认值为60秒。
转载自原文链接, 如需删除请联系管理员。
原文链接:Quartz配置参考,转载请注明来源!