Quartz学习笔记.docx
- 文档编号:27822672
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:11
- 大小:21.03KB
Quartz学习笔记.docx
《Quartz学习笔记.docx》由会员分享,可在线阅读,更多相关《Quartz学习笔记.docx(11页珍藏版)》请在冰豆网上搜索。
Quartz学习笔记
Quartz学习笔记
Quartz特点
1) Quartz能嵌入到任何独立的应用中运行。
2) Quartz能在应用服务器或者Servlet容器中实例化,并且能够参与XA事务。
3) Quartz能够以独立的方式运行(在它自己的Java虚拟机中),可以通过RMI使用
Quartz。
4) Quartz可以被实例化为独立程序的集群(有负载均衡和容错能力)。
Quartz功能介绍
任务执行(JobExecution)
1)任务是任何实现简单Job接口的Java类,这样开发者能够执行任何完成他们工作
的任务。
2)任务类的实例可以由Quartz实例化,也可以由你的程序框架实例化。
当触发器被触发时,日程管理器将会通知某个或者多个实现了JobListener或
TriggerListener的对象(监听器可以是简单的Java对象,或者EJBs,或者JMS消息发布器,等等)。
这些监听器在任务执行完毕后也会接到通知。
3)任务被完成后,他们会返回一个“任务完成码(JobCompletionCode)”,这个
“任务完成码”告知日程管理器任务执行的结果是成功还是失败。
日程管理器会根据成功或者失败码来采取措施,比如:
立即重新执行任务
任务持久化(JobPersistence)
1)Quartz设计中包括了一个JobStore接口,这样,实现这个接口的Job多种机制实现Job的存储。
2)存储在数据库中:
通过使用JDBCJobStore,所有的Jobs和Triggers被配置为“non-volatile”(不
轻快)的方式。
即,通过JDBC存储在关系数据库中。
3)存储在RAM中:
通过使用RAMJobStore,所有Jobs和Triggers被存储在RAM。
因此,在程序执行中没有被持久化,但这种方式的优点就是不需要外部数据库。
事务(Transactions)
1)Quartz通过JobStoreCMT(JDBCJobStore的一个子类)可参与JTA事务。
2)Quartz可以管理JTA(工作任务分析)事务(开始或者提交事务)。
集群(Clustering)
1)Fail-over.(容错)
2)Loadbalancing.(负载均衡)
监听器及插件(Listeners&Plug-Ins)
1)应用可以通过实现一个或者多个监听器接口来实现捕捉日程事件,以监视或控制任务/触发器的行为。
2)可以通过插件的机制来扩展Quartz的功能。
例如:
记录任务执行历史的日志,或者从文件中载入任务和触发器的定义。
3)Quartz自带了一些“factorybuilt(内建)”的插件和监听器。
什么是Quartz
Quartz是一个任务日程管理系统,这个系统可以与任何其他软件系统集成或者一起
用。
“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
Quartz相当“轻量”,并且需要非常少的步骤/配置,如果需求比较基本,Quartz确实非常容易使用。
Quartz具有容错性,并且可以在你系统重起的时候持久化(记住)被纳入日程的任务。
Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。
这些功能的主要接口(API)是Scheduler接口。
它提供了简单的操作,例如:
将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。
如果你想将软件组件的执行纳入到日程中,它们只需简单地实现Job接口,这个接口有一个execute()方法。
如果希望在日程安排的时间到达时通知组件,那么这些组件应实现TriggerListener或者JobListener接口。
Quartz主过程可以在应用中启动或者运行,也可以作为一个独立的应用(带有RMI<远程服务接口>接口),或者在一个J2EE应用服务器中运行,并且可作为其它J2EE组件的一种引用资源。
Quartz与java.util.Timer(JDK1.3起)的区别
1.Java定时器没有持久化机制。
2.Java定时器的日程管理不够灵活(只能设置开始时间、重复的间隔,设置特定的日期、时间等)
3.Java定时器没有使用线程池(每个Java定时器使用一个线程)
4.Java定时器没有切实的管理方案,你不得不自己完成存储、组织、恢复任务的措施。
夏令时和触发器
SimpleTrigger总是每隔若干毫秒触发,而同夏令时没有关系。
CronTrigger总是在给定的时间触发,然后计算它下次触发的时间。
开始使用Quartz
Job:
接口:
只有一个方法:
oidexecute(JobExecutionContextcontext)。
JobDetail:
Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。
因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。
通过该类的构造函数可以更具体地了解它的功用:
JobDetail(java.lang.Stringname,java.lang.Stringgroup,java.lang.ClassjobClass),该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称;
Trigger:
是一个类,描述触发Job执行的时间触发规则。
主要有SimpleTrigger和CronTrigger这两个子类。
当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:
如每早晨9:
00执行,周一、周三、周五下午5:
00执行等。
Calendar:
org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。
一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。
Scheduler:
代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。
Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。
Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。
一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。
可以通过SchedulerFactory创建一个Scheduler实例。
Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。
SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。
可以通过Scheduler#getContext()获取对应的SchedulerContext实例。
ThreadPool:
Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。
Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用不同的执行方案。
无状态任务在执行时拥有自己的JobDataMap拷贝,对JobDataMap的更改不会影响下次的执行。
而有状态任务共享共享同一个JobDataMap实例,每次任务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。
如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。
Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。
不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。
监听体系:
Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。
SimpleTrigger:
SimpleTrigger拥有多个重载的构造函数,用以在不同场合下构造出对应的实例:
1) SimpleTrigger(Stringname,Stringgroup):
通过该构造函数指定Trigger所属组和名称;
2) SimpleTrigger(Stringname,Stringgroup,DatestartTime):
除指定Trigger所属组和名称外,还可以指定触发的开发时间。
3) SimpleTrigger(Stringname,Stringgroup,DatestartTime,DateendTime,intrepeatCount,longrepeatInterval):
除指定以上信息外,还可以指定结束时间、重复执行次数、时间间隔等参数;
4) SimpleTrigger(Stringname,Stringgroup,StringjobName,StringjobGroup,DatestartTime,DateendTime,intrepeatCount,longrepeatInterval):
这是最复杂的一个构造函数,在指定触发参数的同时,还通过jobGroup和jobName,让该Trigger和Scheduler中的某个任务关联起来。
CronTrigger:
Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成,如表1所示:
分别代表秒、分钟、小时、日期、月份、星期、年
位置
时间域名
允许值
允许的特殊字符
1
秒
0-59
-*/
2
分钟
0-59
-*/
3
小时
0-23
-*/
4
日期
1-31
-*?
/LWC
5
月份
1-12
-*/
6
星期
1-7
-*?
/LC#
7
年(可选)
空值1970-2099
-*/
Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下:
1) 星号(*):
可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;
2) 问号(?
):
该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符;
3) 减号(-):
表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;
4) 逗号(,):
表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;
5) 斜杠(/):
x/y表达一个等步长序列,x为起始值,y为增量步长值。
如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;
6) L:
该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。
L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。
但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后一个星期五;
7) W:
该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。
例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。
但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。
W字符串只能指定单一日期,而不能指定日期范围;
8) LW组合:
在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;
9) 井号(#):
该字符只能在星期字段中使用,表示当月某个工作日。
如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;
10) C:
该字符只在日期和星期字段中使用,代表“Calendar”的意思。
它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。
例如5C在日期字段中就相当于日历5日以后的第一天。
1C在星期字段中相当于Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成,如表1所示:
下面给出一些表达式实例:
表示式
说明
"0012**?
"
每天12点运行
"01510?
**"
每天10:
15运行
"01510**?
"
每天10:
15运行
"01510**?
*"
每天10:
15运行
"01510**?
2008"
在2008年的每天10:
15运行
"0*14**?
"
每天14点到15点之间每分钟运行一次,开始于14:
00,结束于14:
59。
"00/514**?
"
每天14点到15点每5分钟运行一次,开始于14:
00,结束于14:
55。
"00/514,18**?
"
每天14点到15点每5分钟运行一次,此外每天18点到19点每5钟也运行一次。
"00-514**?
"
每天14:
00点到14:
05,每分钟运行一次。
"010,4414?
3WED"
3月每周三的14:
10分到14:
44,每分钟运行一次。
?
"01510?
*MON-FRI"
每周一,二,三,四,五的10:
15分运行。
"0151015*?
"
每月15日10:
15分运行。
"01510L*?
"
每月最后一天10:
15分运行。
"01510?
*6L"
每月最后一个星期五10:
15分运行。
"01510?
*6L2007-2009"
在2007,2008,2009年每个月的最后一个星期五的10:
15分运行。
"01510?
*6#3"
每月第三个星期五的10:
15分运行。
任务调度信息存储
在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。
不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。
其实QuartzJAR文件的org.quartz包下就包含了一个quartz.properties属性配置文件并提供了默认设置。
如果需要调整默认配置,可以在类路径下建立一个新的quartz.properties,它将自动被Quartz加载并覆盖默认的设置。
解析配置文件:
①集群的配置,这里不使用集群
org.quartz.scheduler.instanceName=DefaultQuartzScheduler
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
②配置调度器的线程池
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
③配置任务调度现场数据保存机制
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
如果需要修改,使用数据库保存任务调度现场数据
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix=QRTZ_ ①数据表前缀
org.quartz.jobStore.dataSource=qzDS ②数据源名称
③定义数据源的具体属性
org.quartz.dataSource.qzDS.driver=oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.qzDS.URL=jdbc:
oracle:
thin:
@localhost:
1521:
ora9i
org.quartz.dataSource.qzDS.user=stamen
org.quartz.dataSource.qzDS.password=abc
org.quartz.dataSource.qzDS.maxConnections=10
注意:
如果你使用JDBC保存任务调度数据时,当你运行代码清单2的SimpleTriggerRunner然后退出,当再次希望运行SimpleTriggerRunner时,系统将抛出JobDetail重名的异常:
因为每次调用Scheduler#scheduleJob()时,Quartz都会将JobDetail和Trigger的信息保存到数据库中,如果数据表中已经同名的JobDetail或Trigger,异常就产生了。
小结
Quartz提供了最为丰富的任务调度功能,不但可以制定周期性运行的任务调度方案,还可以让你按照日历相关的方式进行任务调度。
Quartz框架的重要组件包括Job、JobDetail、Trigger、Scheduler以及辅助性的JobDataMap和SchedulerContext。
Quartz拥有一个线程池,通过线程池为任务提供执行线程,你可以通过配置文件对线程池进行参数定制。
Quartz的另一个重要功能是可将任务调度信息持久化到数据库中,以便系统重启时能够恢复已经安排的任务。
此外,Quartz还拥有完善的事件体系,允许你注册各种事件的监听器。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Quartz 学习 笔记