Quartz是一个开源的作业调度框架它完全由Java写成并设计用于JSE和JEE应用中它提供了巨大的灵活性而不牺牲简单性你能够用它来为执行一个作业而创建简单的或复杂的调度它有很多特征如数据库支持集群插件EJB作业预构建JavaMail及其它支持cronlike表达式等等 你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上或许仅仅每个月的最后一天执行一个自动执行而无须干预的任务在执行过程中如果发生一个严重错误应用能够知到其执行失败并尝试重新执行吗?你和你的团队是用Java编程吗?如果这些问题中任何一个你回答是那么你应该使用Quartz调度器 旁注Matrix目前就大量使用到了Quartz比如排名统计功能的实现在Jmatrix里通过Quartz定义了一个定时调度作业在每天凌晨一点作业开始工作重新统计大家的Karma和排名等还有RSS文件的生成也是通过Quartz定义作业每隔半个小时生成一次RSS XML文件 Quartz让作业调度简单 Quartz是一个完全由Java编写的开源作业调度框架不要让作业调度这个术语吓着你尽管Quartz框架整合了许多额外功能但就其简易形式看你会发现它易用得简直让人受不了!简单地创建一个实现orgquartzJob接口的Java类Job接口包含唯一的方法 在你的Job接口实现类里面添加一些逻辑到execute()方法一旦你配置好Job实现类并设定好调度时间表Quartz将密切注意剩余时间当调度程序确定该是通知你的作业的时候Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情无需报告任何东西给调度器或调用任何特定的东西仅仅执行任务和结束任务即可如果配置你的作业在随后再次被调用Quartz框架将在恰当的时间再次调用它 如果你使用了其它流行的开源框架象struts你会对Quartz的设计和部件感到舒适虽然两个开源工程是解决完全不同的问题还是有很多相似的之处就是开源软件用户每天感觉很舒适Quartz能用在单机JSE应用中作为一个RMI服务器也可以用在web应用中甚至也可以用在JEE应用服务器中 Quartz的发展史 尽管Quartz今年开始受到人们注意但还是暂时流行Quartz由James House创建并最初于年春天被加入sourceforge工程接下来的几年里有许多新特征和版本出现但是直到项目迁移到新的站点并成为OpenSymphony项目家族的一员才开始真正启动并受到应有的关注 James House仍然和几个协助他的业余开发者参与大量开发工作Quartz开发团队今年能发布几个新版本包括当前正处在候选发布阶段的版 上手Quartz Quartz工程驻留在OpenSymphony站点上在Quartz站点上可以找到许多有用的资源JavaDocs包含指南的文档CVS访问用户和开发者论坛的连接当然也有下载 从下载连接取得Quartz的发布版本并且解压到到本地目录这个下载文件包含了一个预先构建好的Quartz二进制文件(quartzjar)你可以将它放进自己的应用中Quartz框架只需要少数的第三方库并且这些三方库是必需的你很可能已经在使用这些库了 你要把Quartz的安装目录的/lib/core 和 /lib/optional目录中的第三方库加进你自己的工程中大多数第三方库是我们所熟知和喜欢的标准Jakarta Commons库像Commons Logging Commons BeantUtils等等 quartzproperties文件 Quartz有一个叫做quartzproperties的配置文件它允许你修改框架运行时环境缺省是使用Quartzjar里面的quartzproperties文件当然你应该创建一个quartzproperties文件的副本并且把它放入你工程的classes目录中以便类装载器找到它 一旦将Quartzjar文件和第三方库加到自己的工程里面并且quartzproperties文件在工程的classes目录中就可以创建作业了然而在做这之前我们暂且回避一下先简短讨论一下Quartz架构 Quartz内部架构 在规模方面Quartz跟大多数开源框架类似大约有个Java类和接口并被组织到个包中这可以和Apache Struts把大约个类和接口以及组织到个包中相比尽管规模几乎不会用来作为衡量框架质量的一个特性但这里的关键是quarts内含很多功能这些功能和特性集是否成为或者应该成为评判一个开源或非开源框架质量的因素 Quartz调度器 Quartz框架的核心是调度器调度器负责管理Quartz应用运行时环境调度器不是靠自己做所有的工作而是依赖框架内一些非常重要的部件Quartz不仅仅是线程和线程管理为确保可伸缩性Quartz采用了基于多线程的架构 启动时框架初始化一套worker线程这套线程被调度器用来执行预定的作业这就是Quartz怎样能并发运行多个作业的原理Quartz依赖一套松耦合的线程池管理部件来管理线程环境本文中我们会多次提到线程池管理但Quartz里面的每个对象是可配置的或者是可定制的所以例如如果你想要插进自己线程池管理设施我猜你一定能! 作业 用Quartz的行话讲作业是一个执行任务的简单Java类任务可以是任何Java代码只需你实现orgquartzJob接口并且在出现严重错误情况下抛出JobExecutionException异常即可 Job接口包含唯一的一个方法execute()作业从这里开始执行一旦实现了Job接口和execute()方法当Quartz确定该是作业运行的时候它将调用你的作业Execute()方法内就完全是你要做的事情下面有一些你要在作业里面做事情的例子 · 用JavaMail(或者用其他的像Commons Net一样的邮件框架)发送邮件 · 创建远程接口并且调用在EJB上的方法 · 获取Hibernate Session查询和更新关系数据库里的数据 · 使用OSWorkflow并且从作业调用一个工作流 · 使用FTP和到处移动文件 · 调用Ant构建脚本开始预定构建 这种可能性是无穷的正事这种无限可能性使得框架功能如此强大Quartz给你提供了一个机制来建立具有不同粒度的可重复的调度表于是你只需创建一个Java类这个类被调用而执行任务 作业管理和存储 作业一旦被调度调度器需要记住并且跟蹤作业和它们的执行次数如果你的作业是分钟后或每秒调用这不是很有用事实上作业执行需要非常准确和即时调用在被调度作业上的execute()方法Quartz通过一个称之为作业存储(JobStore)的概念来做作业存储和管理 有效作业存储 Quartz提供两种基本作业存储类型第一种类型叫做RAMJobStore它利用通常的内存来持久化调度程序信息这种作业存储类型最容易配置构造和运行对许多应用来说这种作业存储已经足够了 然而因为调度程序信息是存储在被分配给JVM的内存里面所以当应用程序停止运行时所有调度信息将被丢失如果你需要在重新启动之间持久化调度信息则将需要第二种类型的作业存储 第二种类型的作业存储实际上提供两种不同的实现但两种实现一般都称为JDBC作业存储两种JDBC作业存储都需要JDBC驱动程序和后台数据库来持久化调度程序信息这两种类型的不同在于你是否想要控制数据库事务或这释放控制给应用服务器例如BEAs WebLogic或Jboss(这类似于JEE领域中Bean管理的事务和和容器管理事务之间的区别)这两种JDBC作业存储是 · JobStoreTX当你想要控制事务或工作在非应用服务器环境中是使用 · JobStoreCMT当你工作在应用服务器环境中和想要容器控制事务时使用 JDBC作业存储为需要调度程序维护调度信息的用户而设计 作业和触发器 Quartz设计者做了一个设计选择来从调度分离开作业Quartz中的触发器用来告诉调度程序作业什么时候触发框架提供了一把触发器类型但两个最常用的是SimpleTrigger和CronTriggerSimpleTrigger为需要简单打火调度而设计 典型地如果你需要在给定的时间和重复次数或者两次打火之间等待的秒数打火一个作业那么SimpleTrigger适合你另一方面如果你有许多复杂的作业调度那么或许需要CronTrigger CronTrigger是基于Calendarlike调度的当你需要在除星期六和星期天外的每天上午点半执行作业时那么应该使用CronTrigger正如它的名字所暗示的那样CronTrigger是基于Unix克隆表达式的 作为一个例子下面的Quartz克隆表达式将在星期一到星期五的每天上午点分执行一个作业 ? * MONFRI 下面的表达式 ? * L 将在年到年的每个月的最后一个星期五上午点分执行作业你不可能用SimpleTrigger来做这些事情你可以用两者之中的任何一个但哪个跟合适则取决于你的调度需要 调度一个作业 让我们通过看一个例子来进入实际讨论现假定你管理一个部门无论何时候客户在它的FTP服务器上存储一个文件都得用电子邮件通知它我们的作业将用FTP登陆到远程服务器并下载所有找到的文件 然后它将发送一封含有找到和下载的文件数量的电子邮件这个作业很容易就帮助人们整天从手工执行这个任务中解脱出来甚至连晚上都无须考虑我们可以设置作业循环不断地每秒检查一次而且工作在×模式下这就是Quartz框架完全的用途 首先创建一个Job类将执行FTP和Email逻辑下例展示了Quartz的Job类它实现了orgquartzJob接口 我们故意让ScanFTPSiteJob保持很简单我们为这个例子创建了一个叫做JobUtil的实用类它不是Quartz的组成部分但对构建各种作业能重用的实用程序库来说是有意义的我们可以轻易将那种代码组织进作业类中quarts 调度器一样好用因为我们一直在使用quarts所以那些代码可继续重用 JobUtilcheckForFiles() and JobUtilsendEmail()方法使用的参数是Quartz创建的JobDataMap的实例实例为每个作业的执行而创建它是向作业类传递配置参数的方法 这里并没有展示JobUtil的实现但我们能用Jakarta上的Commons Net轻易地实现FTP和Email功能 用调度器调用作业 首先创建一个作业但为使作业能被调度器调用你得向调度程序说明你的作业的调用时间和频率这个事情由与作业相关的触发器来完成因为我们仅仅对大约每秒循环调用作业感兴趣所以打算使用SimpleTrigger 作业和触发器通过Quartz调度器接口而被调度我们需要从调度器工厂类取得一个调度器的实例最容易的办法是调用StdSchedulerFactory这个类上的静态方法getDefaultScheduler() 使用Quartz框架你需要调用start()方法来启动调度器例的代码遵循了大多数Quartz应用的一般模式创建一个或多个作业创建和设置触发器用调度器调度作业和触发器启动调度器 编程调度同声明性调度 我们通过编程的方法调度我们的ScanFTPSiteJob作业就是说我们用Java代码来设置作业和触发器Quartz框架也支持在xml文件里面申明性的设置作业调度申明性方法允许我们更快速地修改哪个作业什么时候被执行 Quartz框架有一个插件这个插件负责读取xml配置文件xml配置文件包含了关于启动Quartz应用的作业和触发器信息所有xml文件中的作业连同相关的触发器都被加进调度器你仍然需要编写作业类但配置那些作业类的调度器则非常动态化你可以将xml文件中的元素跟例代码作个比较它们从概念上来看是相同的使用申明性方法的好处是维护变得极其简单只需改变xml配置文件和重新启动Quartz应用即可无须修改代码无须重新编译无须重新部署 有状态和无状态作业 在本文中你所看到的作业到是无状态的这意味着在两次作业执行之间不会去维护作业执行时JobDataMap的状态改变如果你需要能增删改JobDataMap的值而且能让作业在下次执行时能看到这个状态改变则需要用Quartz有状态作业 如果你是一个有经验的EJB开发者的话深信你会立即退缩因为有状态带有负面含义这主要是由于EJB带来的伸缩性问题Quartz有状态作业实现了orgquartzStatefulJob接口 无状态和有状态作业的关键不同是有状态作业在每次执行时只有一个实例大多数情况下有状态的作业不回带来大的问题然而如果你有一个需要频繁执行的作业或者需要很长时间才能完成的作业那么有状态作业可能给你带来伸缩性问题 Quartz框架的其他特征 Quartz框架有一个丰富的特征集事实上quarts有太多特性以致不能在一种情况中全部领会下面列出了一些有意思的特征但没时间在此详细讨论 监听器和插件 每个人都喜欢监听和插件今天几乎下载任何开源框架你必定会发现支持这两个概念监听是你创建的Java类当关键事件发生时会收到框架的回调例如当一个作业被调度没有调度或触发器终止和不再打火时这些都可以通过设置来来通知你的监听器Quartz框架包含了调度器监听作业和触发器监听你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听 一旦你的一个具体监听被调用你就能使用这个技术来做一些你想要在监听类里面做的事情例如你如果想要在每次作业完成时发送一个电子邮件你可以将这个逻辑写进作业里面也可以JobListener里面写进JobListener的方式强制使用松耦合有利于设计上做到更好 Quartz插件是一个新的功能特性无须修改Quartz源码便可被创建和添加进Quartz框架他为想要扩展Quartz框架又没有时间提交改变给Quartz开发团队和等待新版本的开发人员而设计如果你熟悉Struts插件的话那么完全可以理解Quartz插件的使用 与其Quartz提供一个不能满足你需要的有限扩展点还不如通过使用插件来拥有可修整的扩展点 集群Quartz应用 Quartz应用能被集群是水平集群还是垂直集群取决于你自己的需要集群提供以下好处 · 伸缩性 · 搞可用性 · 负载均衡 目前Quartz只能借助关系数据库和JDBC作业存储支持集群将来的版本这个制约将消失并且用RAMJobStore集群将是可能的而且将不需要数据库的支持 Quartz web应用 使用框架几个星期或几个月后Quartz用户所显示的需求之一是需要集成Quartz到图形用户界面中目前Quartz框架已经有一些工具允许你使用Java servlet来初始化和启动Quartz一旦你可以访问调度器实例你就可以把它存储在web容器的servlet上下文中(ServletContext中)并且可以通过调度器接口管理调度环境 幸运的是一些开发者已正影响着单机Quartz web应用它用来更好地管理调度器环境构建在若干个流行开源框架如Struts和Spring之上的图形用户界面支持很多功能这些功能都被包装进一个简单接口 Quartz的下一步计划 Quartz是一个活动中的工程Quartz开发团队明确表示不会停留在已有的荣誉上Quartz下一个主要版本已经在启动中你可以在OpenSymphony的 wiki上体验一下Quartz 的设计和特征总之Quartz用户每天都自由地添加特性建议和设计创意以便能被核心框架考虑(看重) 了解更多Quartz特征 当你开始使用Quartz框架的更多特性时User and Developer Forum论坛变成一个回答问题和跟其他Quartz用户沟通的极其有用的资源经常去逛逛这个论坛时很有好处的你也可以依靠James House来共享与你的需要相关的知识和意见 |