《HAP框架-定时调度器使用手册-精品文档资料整理.docx》由会员分享,可在线阅读,更多相关《HAP框架-定时调度器使用手册-精品文档资料整理.docx(19页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、192016-07-03,定式调度器开发入门Author:HuojianpingCreation Date:2016-07-03Last Updated:2016-07-10Document Ref:Hap框架定时调度器入门Version:1.0Note: Title, Subject, Last Updated Date, Reference Number, andVersion are marked by a Word Bookmark so that they can be easily reproduced in the header and footer of documents.
2、When you change any of these values, be careful not to accidentally delete the bookmark. You can make bookmarks visible by selecting Tools-OptionsView and checking the Bookmarks option in the Show region.Note:1. To add additional approval lines, press Tab from the last cell in the table above.Note:
3、You can delete any elements of this cover page that you do not need for your document. For example, Copy Number is only required if this is a controlled document and you need to track each copy that you distribute.文档控制更改记录日期作者版本更改参考2016-07-031.0无前版本内容目录文档控制2更改记录2内容目录3一、基本概念41.Quartz的基本认知42.Quartz Jo
4、b接口概述43.Quartz中的Schedule,Trigger,JobDetail5二、HelloWorld实例11三、总结161.任务状态162.触发器163.Quartz表16四、常见问题181.任务触发182.存在同一个Job被多个Trigger触发的情况18问题统计19未结问题19已结问题19一、 基本概念1. Quartz的基本认知Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。Quartz框架包含了
5、调度器监听、作业和触发器监听。你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听。2. Quartz Job接口概述2.1 org.quartz.Job接口Quartz虽然整合了很多额外的功能,但就其本质的作业调度功能来看,使用起来相当的便捷,只需简单的创建一个实现org.quartz.Job接口的Java类。Job接口包含的唯一方法:public void execute(JobExecutionContext context)throws JobExecutionException;在你的Job接口实现类里面,添加一些逻辑到execute()方法。一旦你配置好Job实现类并
6、设定好调度时间表,Quartz将密切注意剩余时间。当调度程序确定该是通知你的作业的时候,Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情。无需报告任何东西给调度器或调用任何特定的东西。仅仅执行任务和结束任务即可。如果配置你的作业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。2.2 com.hand.hap.job.AbstractJob抽象类但是execute()方法有一个缺点,就是它在运行时是无法抛出异常的,一旦进行了异常的抛出,当前Job就会自动被停止,那么为了获取更为详细的运行时的相关信息,Hap框架对Job接口进行了一次封装,封
7、装了一个AbstractJob的抽象类来实现Job接口:public abstract class AbstractJob implements Job在该类中,我们自定义了一个safeExecute(JobExecutionContext context)Throws Exception方法,并让该方法默认在execute()方法中被调用,这样我们就能达到在Job出错时抛出异常的目的了,综上所述,我们想在Hap框架中定义一个我们自己的Job,我们只需要新建一个继承了AbstractJob的类就可以了,在safeExecute()方法中加上我们的一些逻辑,这个Job就会自动的根据自定义的规则(
8、Trigger)被挂起。(Ps:该方法里的JobExecutionContext context参数会在后面做出解释。)3. Quartz中的Schedule,Trigger,JobDetail这里着重给代价介绍一下Quartz中几个重要的对象,JobDetail(具体可执行的调度程序),Trigger(调度参数的配置),Schedule(调度容器)。这三个对象,是实现Quartz的任务调度必不可少的。3.1 JobDetailJobDetail代表了一个具体的、可被执行的任务,即实现了Job接口。下面,我将详细给大家介绍一下JobDetail具体代表什么,以及在Hap框架中如何创建一个Job
9、Detail。3.1.1 JobDetailJobDetai就是一个具体的可执行任务,我们在这要弄清楚它和Job的区别,Job只是为我们提供了一个会自动去调用的execute()方法,我们在这个方法里填充我们的逻辑。而JobDetail则是一个完整的任务对象,这个对象里除了告诉我们该去调用哪一个Job类去实现什么方法,还包含了调用这个Job的相关信息,例如Job的分组,Job的名字等等这张图就代表创建一个简单的JobDetail对象。3.1.2 JobCreateDto与JobDetailJobCreateDto是Hap框架中自定义的一个简单的接收Job相关信息的Dto类,我们通过这个Dto类
10、来接受页面上传回来的相关属性,例如这个Job的方法组、方法名、具体调用哪一个Job类以及相关的策略信息。通过这个JobCreateDto,我们可以接收到页面上的值,然后我们就可以根据这些值来生成JobDetail和Trigger以及Schedule。没错,我们虽然是生成了一个JobCreateDto,但是我们的调度器是不认识这个Dto的,我们需要借助JobBuilder来把JobCreateDto转化成调度器认识的JobDetail。经过这样的转化之后,我们就完成了我们调度器需要的JobDetail的生成。3.2 TriggerTrigger代表的是调度Job是遵循的策略(触发器),比如什么时
11、候将这个任务挂起,什么时候停止这个任务。一个Trigger对应一个Job,但是一个Job却可以有多个Trigger来进行管理,与JobDetail一样,我们需要通过JobCreateDto里面接收到的属性来生成相应的Trigger,这次我们使用的方法是TriggerBuilder。这里我们可以重点关注一下我红框中所标注的方法,一个Trigger就是通过这个.forJob()方法来表示这个Trigger是与哪一个JobDetail相匹配的。3.3 ScheduleSchedule的意思是容器,顾名思义就是用来存放JobDetail和Trigger的,当两者在容器中注册好之后,相匹配的JobDet
12、ail和Trigger就形成了一个完整的作业,那么当这个容器启动之后,里面的作业就会自动的去开始运行了,三者的大体结构类似于:相同的,Schedule也是根据JobCreateDto的相关属性来生成的。在三者都生成之后,我们调用Schedule的.scheduleJob()方法,将相应的JobDetail和Trigger存入其中完成注册之后,我们的一个调度程序就完成了。3.4 小结总结一下,我们想要完成一个调度程序的创建,我们的步骤是:1) 通过页面完成JobCreateDto的封装;2) 根据JobCreateDto的属性,通过JobBuilder()来生成调度器认识的JobDetail;3
13、) 根据JobCreateDto的属性,通过TriggerBuilder()来生成调度器认识的Trigger;4) 根据JobCreateDto的属性,通过ScheduleBuilder()来生成调度器认识的Schedule;5) 使用Schedule.scheduleJob(JobDeatil, Trigger),完成一个完整作业的注册。Tips:CRON表达式:Quartz有两种Trigger,一个是SimpleTrigger,另一个就是CronTigger,CronTrigger能够提供复杂的触发器表达式的支持。CronTrigger是基于Unix Cron守护进程,它是一个调度程序,支
14、持简单而强大的触发器语法。-上面两张图是等价的,只不过下面一张使用的就是CRON表达式,代表的是每分钟的第零秒就会执行这个方法。Cron表达式举例:30 * * * * ? 每半分钟触发任务30 10 * * * ? 每小时的10分30秒触发任务30 10 1 * * ? 每天1点10分30秒触发任务30 10 1 20 * ? 每月20号1点10分30秒触发任务30 10 1 20 10 ? * 每年10月20号1点10分30秒触发任务30 10 1 20 10 ? 2011 2011年10月20号1点10分30秒触发任务30 10 1 ? 10 * 2011 2011年10月每天1点10分
15、30秒触发任务30 10 1 ? 10 SUN 2011 2011年10月每周日1点10分30秒触发任务15,30,45 * * * * ? 每15秒,30秒,45秒时触发任务15-45 * * * * ? 15到45秒内,每秒都触发任务15/5 * * * * ? 每分钟的每15秒开始触发,每隔5秒触发一次15-30/5 * * * * ? 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次0 0/3 * * * ? 每小时的第0分0秒开始,每三分钟触发一次0 15 10 ? * MON-FRI 星期一到星期五的10点15分0秒触发任务0 15 10 L * ? 每个月最后一天的10点15
16、分0秒触发任务0 15 10 LW * ? 每个月最后一个工作日的10点15分0秒触发任务0 15 10 ? * 5L 每个月最后一个星期四的10点15分0秒触发任务0 15 10 ? * 5#3 每个月第三周的星期四的10点15分0秒触发任务这里就介绍这么多,有兴趣的童鞋可以参考下面链接里的相关资料。Tutorial - Lesson 6: CronTrigger;Spring - Quartz - cronExpression中问号(?)的解释 二、 HelloWorld实例在上面的讲解之后,相信大家对Job的调度有了一定的理解,那么我们就用一个简单的实例来给大家梳理一下整个流程,加深一下
17、大家的印象。因为Trigger有两种形式,也就是SimpleTrigger和CronTrigger,而CronTrigger能处理更加复杂的时间表达格式,它的使用范围更大,所以这里我们以CronTrigger为例:1) 首先,点击项目页面上的任务详情,我们可以看到对Job进行管理的界面,点击新建Cron任务或简单任务,我们就可以在弹出窗口上完善我们的Job信息;2) 在Job信息的完善页面,补充我们需要的相应信息来生成一个完善的JobCreateDto;在上图我们可以看到我们在新建Cron任务页面上填写任务类名,就是对应这里的后台HelloWorldJob,这个类继承了我们框架中封装好的Abs
18、tractJob,也就是实现了Job接口,证明这是一个可以被调度的Job类,而这个类的作用也很简单,就是在控制台通过logger来打印一句话而已。3) JobCreateDto生成完成之后,我们就会在后台进行JobDetail的生成,具体方法可以参见com.hand.hap.job.service.impl中QuzrtzServiceImpl的CreateJob方法:4) JobDetail和Trigger完成在Schedule中的作业注册后,JobDetail就会自动根据相应的Trigger来运行;绿色的Job任务代表该任务正在执行中,我们可以在控制台中看到这个Job的相关信息,上图中的红框
19、就是我们Job中打印的一句话。在这需要和大家说明一下,当我们完成一个Job的创建后,这个Job就会马上被执行一次,之后才会匹配我们定义的Trigger来执行。同时,我们每一个Job的执行,都会有一个监听器来对这个Job进行监听,也就是JobRunningListener,感兴趣的童鞋可以去研究一下。(ps:当我们在后台创建完一个线程后,可以在前台直接将这个Job挂起,不用再次重启服务。)另外在项目中quartz.properties文件定义了Quartz应用运行时行为,还包含了许多能控制Quartz运转的属性。它应放在工程的classpath中。童鞋们可以看一看。三、 总结1. 任务状态Qua
20、rtz框架中QRTZ_TRIGGERS表 TRIGGER_STATE 字段显示任务的属性大概状态有这几种: WAITING:等待 PAUSED:暂停 ACQUIRED:正常执行 BLOCKED:阻塞 ERROR:错误2. 触发器Quartz的触发时间的配置有三种方式: cron的方式:采用cronExpression表达式配置时间; simple的方式,和JavaTimer差不多,可以指定一个开始时间和结束时间外加一个循环时间; calendars方式,可以和cron配合使用,用cron表达式指定一个触发时间规律,用calendar指定一个范围。3. Quartz表Quatrz集群调度模式下涉
21、及到如下的相关表:/*job监听器 */SELECT T.*, ROWIDFROM QRTZ_JOB_LISTENERS T;/*触发器监听器*/SELECT T.*, ROWIDFROM QRTZ_TRIGGER_LISTENERS T;/*存放暂停掉的触发器 */SELECT T.*, ROWIDFROM QRTZ_PAUSED_TRIGGER_GRPS T;SELECT T.*, ROWIDFROM QRTZ_LOCKS T;/*存放日历信息, quartz可配置一个日历来指定一个时间范围*/SELECT T.*, ROWIDFROM QRTZ_CALENDARS T;SELECT T.
22、*, ROWIDFROM QRTZ_BLOB_TRIGGERS T;/*存放已触发的触发器 */SELECT T.*, ROWIDFROM QRTZ_FIRED_TRIGGERS T;/*触发器的基本信息*/SELECT T.*, ROWIDFROM QRTZ_TRIGGERS T;/*简单触发器的信息*/SELECT T.*, ROWIDFROM QRTZ_SIMPLE_TRIGGERS T;/*cron类型的触发器的信息*/SELECT T.*, ROWIDFROM QRTZ_CRON_TRIGGERS T;/*存放一个jobDetail信息*/SELECT T.*, ROWIDFROM
23、QRTZ_JOB_DETAILS T;/*调度器状态 */SELECT T.*, ROWIDFROM QRTZ_SCHEDULER_STATE T;四、 常见问题1.任务触发如果出现任务没有触发的情况,可以通过如下手段排查与处理 查询QRTZ_TRIGGERS表的TRIGGER_STATE字段是否为ERROR如果为ERROR,说明可能该任务由其他机器所触发(目前开发使用的是集群调度模式,很可能任务由其他人员机器服务所触发,而触发服务无法调用任务逻辑) QRTZ_TRIGGERS表的TRIGGER_STATE字段如果为ERROR,可以使用如下方式重置:UPDATE QRTZ_TRIGGERS SET TRIGGER_STATE = WAITINGWHERE TRIGGER_STATE = ERROR2.存在同一个Job被多个Trigger触发的情况存在同一个Job被多个Trigger触发的情况?只需要多个Trigger,不需要重复定义多个Job问题统计未结问题序号问题解决方案负责人目标日期实际日期已结问题序号问题解决方案负责人目标日期实际日期Hap框架定时调度器入门File Ref: Hap框架定时调度器入门8d58fd84364dd15b1e0d1e86049d4360.docx (v. 1 )CompanyConfidential - For internal use only
限制150内