`
zhaohaolin
  • 浏览: 986173 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

用quartz实现多任务动态加载【转】

    博客分类:
  • JAVA
 
阅读更多

用quartz实现多任务动态加载

         Hudson报表系统二期结束了,这次新增了邮件定制功能,实现此功能的核心在于quartz框架。

Quartz 是什么

         Quartz是一个用Java编写的任务调度框架,任务调度是什么,举例说明:比如我们需要在每个星期四下午三点时候发周报,我们需要一个系统在两点半的 时候给我们一个发周报的提醒,这个提醒就是一次任务,每周星期四下午两点半的时候自动触发这个任务,这就可以理解为这个系统的一次任务调度。Quartz 提供给我们定时调度已定义好的任务的能力,如果你了解quartz的调度计划cronExpression表达式的配置,你会感叹quartz的灵活与强 大。

         Quartz的应用广泛,对于Hudson报表系统,恰好为邮件定制功能提供强有力的支持。

Quartz 的简单使用

         在Hudson报表系统的一期中也用到了quartz,不过当时是把任务调度信息写死在配置文件中,每次系统启动后,调度的配置都加载在内存中,没有实现 多任务的动态加载。我们先以此来说明quartz的基本用法。Hudson报表系统是用spring框架将quartz整合起来的,故只介绍spring 和quartz的整合使用。

         下图为spring配置文件中quartz的配置:

         其实quartz的使用主要有三个部分,一个调度器Scheduler,一个要被调度的任务JobDetail,一个触发器Trigger,对上面的配置做一说明,在图中从下到上:

1、 配置一个job,这个job就是我们要调度的任务类,

2、 配置jobDetail,jobDetail需要加载job实现类,并且指定目标方法即完成任务需要执行的方法为execute,在这个方法里面定义我们要做的任务,execute方法需要我们在job类中实现。

3、 配置trigger,用于触发我们定义的任务,在触发器的配置中,我们需要加载需要调度的任务jobDetail,当然还要配置好我们需要触发的时间,触 发的时间配置在cronExperssion表达式中,这个表达式非常灵活与强大,举个例子:我们需要每个工作日早八点到晚八点之间,每半个小时触发一次 任务,我们可以将表达式配置为:0 0/30 8-20 ? * MON-FRI。这个表达式的详细解释可以登录Hudson报表系统(链接:http://10.232.29.21:8080/hudson-report/ ),点击邮件信息维护里面的“邮件发送时间计划配置帮助”查看。

4、 配置scheduler,只需要加载trigger即可,可以在list标签下配置多个trigger。注意,scheduler的配置中有个lazy- init=false的配置,这表明只要我们的spring一启动,quartz的scheduler也跟着启动,否则其值为true的话,会因为惰性加 载的问题,导致quartz不起作用,此项默认值是false。

         至此,我们的配置写好了,只需要实现拥有execute方法的job类就可以了。

         这种方法也可以实现多任务调度,具体做法为:我们每新增一个调度,就需要在配置文件中多加这个调度相关的配置,这样显然很麻烦。

Quartz 的多任务动态加载

         先做简要说明:

         多个任务的动态加载是指:在当前的scheduler中已经有可触发的任务的情况下,我们需要新增一条任务进去,并且使得新增的任务也立即加载到 scheduler中,等待触发。要实现这样的功能,上面的方法明显不能达到,而且我们需要使得我们的任务状态持久化,即每次重启quartz后,自动加 载重启前拥有的任务,把任务保存于内存也明显不能达到此目的。怎么办?添加数据库支持,将信息保存于数据表中。

         Quartz的官方文档中提供了在各种类型数据库中建立数据表的sql文件(/docs/dbTables目录下),我们采用MySQL数据库可以选择 tables_mysql_innodb.sql这个文件。这里需要注意的是编码,quartz默认采用latin1编码,我们一般用urf-8或者 gbk编码,建立表的时候会提示表中存在过长的字段,怎么办,改编码?但我们需要中文字符,所以我们可以将过长的字段长度改为支持的长度即可,现阶段并没 有发现副作用。

         建立起来的数据表如下图:

         共十二张表,从上到下依次解释:

         qrtz_blob_triggers:

         qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。

         qrtz_cron_triggers:存放cron类型的触发器

         qrtz_fired_triggers:存放已触发的触发器

         qrtz_job_details:存放一个jobDetail信息

         qrtz_job_listeners:job监听器

         qrtz_locks:

         qrtz_paused_trigger_graps:存放暂停掉的触发器

         qrtz_scheduler_state:调度器状态

         qrtz_simple_triggers:简单触发器的信息

         qrtz_trigger_listeners:触发器监听器

         qrtz_triggers:触发器的基本信息

         Quartz的触发时间的配置有三种方式:

         cron的方式:采用cronExpression表达式配置时间;

         simple的方式,和JavaTimer差不多,可以指定一个开始时间和结束时间外加一个循环时间;

         calendars方式,可以和cron配合使用,用cron表达式指定一个触发时间规律,用calendar指定一个范围。

         我们采用的是cron方式,需要用到的数据表主要是:qrtz_triggers ,qrtz_cron_triggers,qrtz_fired_triggers,qrtz_job_details。

         到这里开始讲到底怎么来实现我们的多任务动态加载。

         其实我们要实现我们的多任务动态调度根本不需要了解这些表,我们要做的只是实现一个做任务的job类,然后新建一个jobDetail,设置参数,新建一个trigger,设置参数,一起加入到scheduler里面去就行了。具体过程如下:

1、  建立数据表,配置好数据库连接。

2、  在Spring的配置文件中配置好schedule:

         其中dataSource配置的是数据库连接,threadCount配置的是容许同时5个任务触发,

startupDelay配置的是触发启动后的时延,这些配置的具体信息大家可以阅读quartz的官方帮助文档来了解。

3、  建立一个用于提供schedule服务的接口ScheduleService及其实现类ScheduleServiceImpl,

         这里提供scheduleJob的方法作为示例,以我们的邮件任务为例,我们直接传入一条邮件记录对象,这个对象拥有id,name,收件人,抄送人,主题,还要有一个cronExpression表达式用于定时发送,看具体实现:

         在上面的方法中,我们要新增一条邮件任务的时候,拿到这个邮件信息对象,先新建一个JobDetail对象,设置参数,setName方法可以给 jobDetail对象指定一个名字,我们希望一条邮件信息对象对应一个jobDetail,故把邮件信息对象的id传入,否则假如两次新增任务时 jobDetail的名字一样,那么后者会覆盖前者的数据,使得前者失效。JopDataMap里面可以保存我们需要传入的业务参数,邮件信息的参数就保 存在邮件信息对象里面,所以我们把整个对象传入,最重要的是setJobClass这个方法,设置了要处理我们任务的类,使得任务触发后quartz知道 去哪里执行任务。最后将此任务加入scheduler。

         然后新建一个CronTrigger对象,构造对象的时候就传入trigger自己的名字和所在组,jobDetail的名字和所在组,设置好 cronExpression表达式,这样此trigger就会按此表达式的计划做触发。需要说明的是:一个jobDetail可以对应多个 trigger,只要在构造时设置trigger名字不同,而jobDetail的名字相同,就可以为相同的jobDetail建立不同的trigger 触发器。而且对于trigger也可以设置jobDataMap,保存此触发器触发时需要的业务参数。

         最后SchedulerJob方法把trigger加入scheduler,等待触发。

4、  建立任务类MyJob,MyJob类需要继承QuartzJobBean类,重载其executeInternal方法:

         在重载executeInternal方法时,其形参jobExecutionContext中包含了触发任务的环境信息,和触发这个任务的jobDetail实例和trigger实例,我们可以从中取得我们想要的信息。

分享到:
评论

相关推荐

    springboot-quartz-demo:quartz实现定制化定时任务-基于springboot

    master分支上是使用springboot+quartz+mysql+kafka实现定制化定时任务功能 系统启动初始化加载已有的定时任务 启动or暂停定时任务 立即运行定时任务 实时新增及修改定时任务 定时任务的详细监控 博客地址: 注意此...

    Quartz开源作业调度库-其他

    Quartz是功能强大的开源作业调度库,几乎可以集成到任何...2、可以使用Plug-In机制为Quartz添加功能,例如保留作业执行的历史记录,或从文件加载作业和触发器定义。 3、Quartz附带了许多“工厂内置”的插件和监听器。

    企业后台管理基础框架 hsweb.zip

    定时任务: 配置定时任务,使用动态脚本编写任务内容.系统监控: 监控系统资源使用情况.缓存监控: 监控缓存情况.访问日志: 记录用户每次操作情况未来:组织架构管理: 地区-机构-部门-职务-人员.工作流管理: activiti...

    Java面试宝典PLUS.pdf

    包括JavaSE基础(多态、异常处理、常用API、数据类型、IO操作、集合、多线程和并发库、内部类)、JavaSE高级(反射、动态代理、设计模式&回收机制、加载器、JVM基础、GC基础)、JavaWeb基础(JDBC技术、HTTP协议、...

    Spring.3.x企业应用开发实战(完整版).part2

    13.3 在Spring中使用Quartz 13.3.1 创建JobDetail 13.3.2 创建Trigger 13.3.3 创建Scheduler 13.4 Spring中使用JDK Timer 13.4.1 Timer和TimerTask 13.4.2 Spring对JDK Timer的支持 13.5 Spring对JDK 5.0 Executor的...

    Spring3.x企业应用开发实战(完整版) part1

    13.3 在Spring中使用Quartz 13.3.1 创建JobDetail 13.3.2 创建Trigger 13.3.3 创建Scheduler 13.4 Spring中使用JDK Timer 13.4.1 Timer和TimerTask 13.4.2 Spring对JDK Timer的支持 13.5 Spring对JDK 5.0 Executor的...

    Spring中文帮助文档

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring API

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4  高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4  高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4  高...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4  高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4  高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4  高...

    搜索指标

    Scheduler不是多实例安全的,为了不过度设计应用程序而省略了它,选项是Quartz或ShedLock 工件版本可以通过依赖管理直接修复,以产生幂等的构建 默认运行配置文件是dev ,默认构建配置文件是prod 运行测试 ./...

    Smart Admin通用型中后台解决方案-其他

    哪些人在偷偷的跑你的Job11、自定义的quartz job添加和修改,方便测试人员测试12、smart-reload,为系统预留钩子,动态加载,在不重启程序前提下执行一些代码,你懂的13、其他功能:邮件、富文本、消息、系统配置...

    Smart Admin通用型中后台解决方案 v1.0.9

    12、smart-reload,为系统预留钩子,动态加载,在不重启程序前提下执行一些代码,你懂的 13、其他功能:邮件、富文本、消息、系统配置等等 14、以上只是一些举例,更多灿若繁星的惊喜和细节,等待着你的发现!...

    单点登录源码

    基于bootstrap实现的响应式Material Design风格的通用后台管理系统,`zheng`项目所有后台系统都是使用该模块界面作为前端展示。 > zheng-ui 各个子系统前台thymeleaf模板,前端资源模块,使用nginx代理,实现动静...

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................

Global site tag (gtag.js) - Google Analytics