Quartz学习(3)

10.配置,资源使用和调度器工厂

 

Quartz是以标准组件的方式组织的,所以,使它运行起来,一些组件需要被联合起来。

 

Quartz能够工作之前,需要配置的主要组件有:

 

线程池

 

作业储存

 

数据源(需要的话)

 

调度器自己

 

在运行jobs时,线程池为Quartz提供了一系列的线程。在线程池里的线程越多,

 

能够并行执行的jobs就越多。但是,太多的线程会使系统瘫痪。大部分的Quartz

 

用户发现,5个线程就足够了-因为他们在指定时间里只有少于100jobs,这些jobs并不都是在同一时刻执行,jobs完成得也很快的。其他的用户发现他们需要101550或者100个线程-因为他们在不同的调度器里用了上万个触发器,在给定的时间里,平均在10100jobs试着执行。为调度器找到合适的线程数量完全依赖于你用调度起来做什么。不在乎线程数量,而要确保你有足够的线程来使jobs执行。如果一个触发器的触发时间到来了,可是没有一个能够用的线程,Quartz将会等到可用线程的来临,然后job将会在几毫秒后执行。这可能会引起不触发-如果不在属性文件里给调度器配置“misfire threshold”的话。

线程池接口是在org.quartz.spi包里定义的,你能够创建一个线程池以自己的方法。Quartz装配了一个简单(但是很好的)的线程池,是org.quartz.simpl.SimpleThreadPool。这个线程池简单的维护一些在池里固定的线程-不会增加也不会减少。但是它能够做很多事而且经过测试了的,几乎每个Quartz用户用这个线程池。

      JobStores  DataSrouces在前面讨论过了,这里值得一提的是,所有JobStores都实现了org.quartz.spi.JobStore接口,如果在打包里的任何一个JobStore不能够满足你的需求的话,你可以自己做一个。

最后,你需要创建你的Scheduler实例。Scheduler需要提供他的名称,说明RMI的设置,处理JobStoreThreadPool的实例。RMI设置包括调度器是否作为一个RMI服务器而创建。StdSchedulerFactory也能够产生调度器的实例,这些实例实际上是创建在远程进程中的调度器代理(RMI桩)。

StdSchedulerFactory

StdSchedulerFactory实现了org.quartz.SchedulerFactory接口。它用了一系列的属性(java.util.Properties)来创建和初始化一个Quartz的调度器。这些属性通常保存和加载在一个文件里,但是也可以通过你的程序创建直接交给工厂处理。在工厂上调用getScheduler()就可以产生调度器,初始化它(还有线程池,JobStore和数据源),然后返回一个句柄到这个公共的接口。

// 默认调度器是quartz.propeties文件定义的,这个文件可以在当前目录下找到,也可以在//classpath里找到,如果都找不到了,就用quartz.jar里的quartz.propeties文件。

SchedulerFactory sf new StdSchedulerFactory();

Scheduler scheduler sf.getScheduler();

scheduler.start();

用指定的属性对象初始化:

SchedulerFactory sf new StdSchedulerFactory();

sf.initialize(schedulerProperties);// schedulerProperties是属性对象

Scheduler scheduler sf.getScheduler();

scheduler.start();

用指定的属性文件初始化:

SchedulerFactory sf new StdSchedulerFactory();

sf.initialize(fileName);//属性文件全名

Scheduler scheduler sf.getScheduler();

scheduler.start();

DirectSchedulerFactory

DirectSchedulerFactory是另外的一个SchedulerFactory实现。在更多的编程方法里创建调度器时,他很有用。他的用法不被赞成,原因有:1.它需要用户更清楚的知道他们在做什么。2.它不允许配置,就是说,你必须要在代码里配置所有的调度器属性。

Logging

Quartz给它所有需要的日志是使用org.apache.commons.logging框架的。Quartz没有产生很多的日志信息。仅有一些在初始化时关于一些jobs正在执行的问题的信息。为了调整日志设置,我们需要了解Jakarta Commons Logging框架,超过了本文档讨论的范围。

 

11.高级(企业)特性

集群

目前集群仅以JDBC-Jobstore (JobStoreTX or JobStoreCMT)工作。这些特性包含load-balancing和任务fail-over(如果JobDetail"request recovery"标志设为true的话)。

通过设置org.quartz.jobStore.isClustered属性为“true”来使用集群。在集群里的每个调度器实例应该用一样的quartz.properties文件。集群会有如下异常:线程池大小不同,属性org.quartz.scheduler.instanceName值不同。其实在集群的每个节点都有一个唯一的实例ID,要达到这样也很简单,也不需要不同的属性文件,只要将属性org.quartz.scheduler.instanceId的值设置为“AUTO”。

不要在一个分离开的机器上运行集群,除非他们的时钟是用时钟同步服务同步过的。如果不熟悉怎样同步,参考:http://www.boulder.nist.gov/timefreq/service/its.htm

其他调度器实例在用数据表时,不要触发一个也用到这些数据表的不是集群的调度器实例。你会得到一些没用的数据。

 

JTA 事务

在第9节解释过JobStoresJobStoreCMT允许Quartz调度一些具有很大JTA事务的操作。

通过设置“org.quartz.scheduler.wrapJobExecutionInUserTransaction”属性为trueJobs也能够在一个JTA事务里执行。有了这个设置,一个JTA事务会在jobexecute()方法调用前开始(begin),然后在调用execute()方法结束后提交(commit)。

除了在JTA事务里Quartz自动地和job的执行挂钩之外,当使用JobStoreCMT时也可以调用你在调度器接口里的实现的方法,确保你在调用一个调度器上的方法之前开始了事务。你也可以直接自己做,使用UserTransaction,或者把用了调度器的代码放在一个使用容器的SessionBean里来管理事务。

12. Quartz 的其他特性

Plug-Ins

Quartz 提供了一个接口(org.quartz.spi.SchedulerPlugin) 来实现plugging-in 的功能。

装配给QuartzPlugins能提供不同的有用的功能。在org.quartz.plugins包里有详细说明他们提供的功能例如:调度器启动时自动调度jobs,记录jobtriggers事件的历史,当JVM退出时确保调度器关闭。

可以通过配置属性文件来使用自己实现或Quartz自带的插件。

JobFactory

当一个trigger触发时,通过一个配置到调度器上的JobFactory,与trigger相关的job就被实例化了。默认的JobFactory会在job类上调用newInstance(),你可能想要创建自己的JobFactory实现来完成一些其他的事情,如:拥有应用程序的IoC或者DI容器进程/初始化job实例。

Scheduler.setJobFactory(fact)方法联合起来察看org.quartz.spi.JobFactory接口,

Jobs工具

Quartz也提供一些有用的job,你能够用这些job来发邮件或者调用EJB。我们能在org.quartz.jobs包里找到它们。

13.配置文件里配置项总结

设置主要调度器

属性名

必须

类型

缺省值

 

org.quartz.scheduler.instanceName

no

string

'QuartzScheduler'

 

org.quartz.scheduler.instanceId

no

string

'NON_CLUSTERED'

 

org.quartz.scheduler.threadName

no

string

instanceName '_QuartzSchedulerThread'

 

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.context.key.SOME_KEY

no

string

none

 

org.quartz.scheduler.userTransactionURL

no

string (url)

'java:comp/UserTransaction'

 

org.quartz.scheduler.wrapJobExecutionInUserTransaction

no

booelan

false

 

org.quartz.scheduler.jobFactory.class

no

string (class name)

org.quartz.simpl.SimpleJobFactory

 

org.quartz.scheduler.instanceName 
任意的String,对于调度器自己并没有意义。但是当多个调度器实例用在一个程序里时,他就可以用来为客户端代码区别每个调度器。如果你用集群这个特性,你必须为在集群里的每个实例用一样的名字,实现逻辑上的一样的调度器。

org.quartz.scheduler.instanceId 
任意的String,如果在一个集群里多个实例是一个逻辑上一样的调度器时,每个实例的这项属性必须唯一。你可以设置这项为“AUTO”从而自动收集ID

org.quartz.scheduler.idleWaitTime 
当调度器空闲时,在再次查询可用triggers之前,调度器将要等等待的毫秒数。正常情况下,我们不调整这个参数,除非我们用XA事务,或者在立即触发trigger时结果延误了。

org.quartz.scheduler.classLoadHelper.class 
不需要更改。

org.quartz.context.key.SOME_KEY

设置org.quartz.context.key.MyKey MyValue等价于scheduler.getContext().put("MyKey", "MyValue")

org.quartz.scheduler.userTransactionURL 
是一个JNDI URLQuartz用它来定位应用服务器的UserTransaction管理器。Websphere用户可能需要设置它为“jta/usertransaction”。在Quartz配置用到JobStoreCMT时并且属性org.quartz.scheduler.wrapJobExecutionInUserTransaction设置为true才有用

org.quartz.scheduler.wrapJobExecutionInUserTransaction 
设置这项为true使我们在调用jobexecute()之前能够开始一个UserTransaction。在jobexecute()完成之后,事务将会提交,并且,JobDataMap也更新了(是有状态的job)。

设置线程池

属性名

必须

类型

缺省值

 

org.quartz.threadPool.class

yes

string (clas name)

null

 

org.quartz.threadPool.threadCount

yes

int

-1

 

org.quartz.threadPool.threadPriority

no

int

Thread.NORM_PRIORITY (5)

 

org.quartz.threadPool.makeThreadsDaemons

no

boolean

false

 

org.quartz.threadPool.threadsInheritGroupOfInitializingThread

no

boolean

true

 

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread

no

boolean

false

 

org.quartz.threadPool.class 
通常使用org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadPriority 
 Thread.MIN_PRIORITY (1) Thread.MAX_PRIORITY (10)之间

org.quartz.threadPool.makeThreadsDaemonsorg.quartz.threadPool.threadsInheritGroupOfInitializingThreadorg.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread 三个属性是指定的SimpleThreadPool的属性。

如果用自己实现的线程池,可如下配置:

org.quartz.threadPool.class com.mycompany.goo.FooThreadPool

org.quartz.threadPool.somePropOfFooThreadPool someValue

设置全局监听器

全局监听器要有一个无参数的构造器,它的属性是通过反射设置的,仅支持简单数据和String

Trigger监听器:

org.quartz.triggerListener.NAME.class com.foo.MyListenerClass

org.quartz.triggerListener.NAME.propName propValue

org.quartz.triggerListener.NAME.prop2Name prop2Value

job监听器:

org.quartz.jobListener.NAME.class com.foo.MyListenerClass

org.quartz.jobListener.NAME.propName propValue

org.quartz.jobListener.NAME.prop2Name prop2Value

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ma_xs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值