最佳实践:利用Quartz实现任务调度的集群_66692.doc
文本预览下载声明
最佳实践:利用Quartz实现任务调度的集群
分类:JAVA
作者:凡彬勇
日期:2012-06-20
导读:Quartz集群的实现
任务调度为什么要实现集群
公众企业应用几乎都会碰到任务调度的需求务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。Java开源的好处就是:领域问题都能找到现成的解决方案。
OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
quartz集群的原理
一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,它又管理着其他的节点。意思是你必须对每个节点分别启动或停止。不像许多应用服务器的集群,独立的 Quartz 节点并不与另一其的节点或是管理节点通信。Quartz 应用是通过数据库表来感知到另一应用的。?图:表示了每个节点直接与数据库通信,若离开数据库将对其他节点一无所知??
集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。目前集群只能工作在JDBC- Jobstore (JobStoreTX 或者JobStoreCMT)方式下,从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的(Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程)。负载平衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务(通过锁定),成为执行任务的节点。故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复(任务详细信息的requests recovery属性)的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行创建Quartz数据库表因为Quartz 集群依赖于数据库,所以必须首先创建Quartz数据库表。Quartz 包括了所有被支持的数据库平台的 SQL 脚本。在 quartz_home/docs/dbTables 目录下找到那些 SQL 脚本,这里的 quartz_home 是解压 Quartz 分发包后的目录。?这里采用的Quartz 1..5版本,总共12张表,不同版本,表个数可能不同。数据库为,用tables_oracle.sql创建数据库表。配置数据库连接池?perties
db.dialect=org.hibernate.dialect.Oracle9Dialect
db.driverClassName=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@:1521:feelview
db.username=feelviewdata
db.password=paic1234
TescronExpression1=0 0/1 * ? * *
其中:TescronExpression1是定时器的crontab表达式(我这里配置的是每分钟跑一次),下面在配置CronTriggerBean的时候会使用到。关于crontab表达式的配置这里不做介绍,在quartz的官方文档有详细介绍
!—全局配置文件读入 --?
bean id=propertyConfigurer
class=org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
property name=locations
list
valueclasspath:perties/value
/list
/property
/bean
!—连接池配置--?
bean id=dataSource class=com.mchange.v2.c3p0.ComboPooledDataSource destroy-metho
显示全部