Quartz Tutorial 9 - Configuration, Resource Usage and SchedulerFactory
Quartz是模块化的架构,因此它运行的时候必定是多个组件互相协作运行的。在Quartz能干活之前主要有如下几个组件需要配置:
- ThreadPool
- JobStore
- DataSources(如果有必要)
- Scheduler
ThreadPool
为Quartz提供了一些可用于执行作业的线程。线程池里的线程数越多,能同时执行的作业也就越多。不过,过多的线程可能会拖累你的系统。大部分Quartz的用户发现5个左右的线程就很充足-因为在任何给定时间,程序的作业都远小于100个,而且也一般不会同时运行,此外作业也一般是短暂存在的(因为完成的很快)。有些用户就发觉他们需要10个、20个、50个甚至100个线程-因为有成百上千个触发器需要调取,而且在任意时刻平均有10到100个作业需要执行。因此可见,你的调度器到底需要多大的线程池完全取决于你要什么。这里没有确定的数字,当然要让这个数字尽可能小(为了尽可能少占用你机器的资源)-但是你也要保证这个数目是够用的。要注意:如果一个触发器到了触发时间了,但是没有闲置线程让它干活,Quartz将会暂停它直到有了可用的县城资源,然后作业才能执行-可能会晚个多少毫秒吧。如果在调度器配置的“misfire阈值”内一直没有可用线程,那么就会引发misfire。
ThreadPool
接口定义在org.quartz.spi
包中,你可以通过任何方式提供该接口的一个实现。Quartz提供了一个简单(但是非常靠谱)的线程池实现,org.quartz.simpl.SimpleThreadPool
。这个线程池内部维护了一个定长线程池-不会扩展也不会收缩-但是相当健壮经过了相当严密的测试,几乎每个用户都在用Quartz提供的这个线程池。
JobStore
和DataSource
刚刚讨论过了。这里值得注意的是,所有的JobStore
都实现了org.quartz.spi.JobStore
接口,那么如果现有的实现满足不了你的需求,自己实现一个。
最后,你需要创建一个调度器实例。调度器自身需要一个名字,告知它的RMI设置,然后给一个JobStore
和ThreadPool
的实例。RMI设置包括调度器是否将自己创建成一个用于RMI的服务对象(可以被远程连接),用什么主机名和端口等等。
StdSchedulerFactory
也可以生成实际上是远程进程创建的调度器实例代理的调度器实例。
StdSchedulerFactory
StdSchedulerFactory
是org.quartz.SchedulerFactory
接口的一个实现。它使用了一系列属性(java.util.Properties
)来创建和初始化Quartz调度器。这些属性一般存储在文件中,但是你也可以直接在程序中创建然后交给工厂类。简单调用一下getScheduler()
方法,工厂类就会实例化一个对象,然后将之初始化(包括线程池、JobStore
和数据源),然后将它的公共接口返回给外界。
在Quartz分支的docs/config目录下有些简单的配置(包括对属性的描述)。在Quartz文档的Reference目录下,手册里的Configuration小节有完整的文档。
DirectSchedulerFactory
DirectorySchedulerFactory
是SchedulerFactory
接口的另一个实现。当你想用编程风格创建一个调度器实例的时候,这就很有用了。但这个一般不鼓励使用,出于以下两个原因:
- 它需要用户对于正在做什么有非常深的理解
- 它不支持声明式的配置-换句话说,你必须完全动手用编码的方式写出调度器的所有设置
Logging
对于所有的日志需求,Quartz使用SLF4J框架。如果你需要调整日志设置(例如调整日志的输出以及它们输出的位置),你需要了解这个框架,但是这个不在本文档的范围内了。
如果你需要捕获更多关于触发器触发和作业执行的信息,你可能需要去了解一下org.quartz.plugins.history.LoggingJobHistoryPlugin
和/或org.quartz.plugins.history.LoggingTriggerHistoryPlugin
。