欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Quartz任务调度

程序员文章站 2023-11-16 17:33:28
一、Quartz概述: Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间。其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。主要用来执行定时任务,如:定时发送信息、定时生成报表等等。 二、相关术语: 调度器S ......

一、quartz概述:

       quartz是一个完全由java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间。其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。主要用来执行定时任务,如:定时发送信息、定时生成报表等等。

二、相关术语:

       调度器scheduler :quartz框架的核心是调度器。调度器负责管理quartz应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。quartz不仅仅是线程和线程池管理。为确保可伸缩性,quartz采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。这就是quartz怎样能并发运行多个作业的原理。quartz依赖一套松耦合的线程池管理部件来管理线程环境。
      任务jobdetail:这个很简单,就是我们自己编写的业务逻辑,交给quartz帮我们执行 。
      触发器trigger :简单的讲就是调度作业,什么时候开始执行,什么时候结束执行。

三、quartz的体系结构简介:

       quartz框架主要核心组件包括调度器、触发器、作业。调度器作为作业的总指挥,触发器作为作业的操作者,作业为应用的功能模块。其关系如下图所示:

Quartz任务调度

 job为作业的接口,为任务调度的对象;jobdetail用来描述job的实现类及其它相关的静态信息;trigger做为作业的定时管理工具,一个trigger只能对应一个作业实例,而一个作业实例可对应多个触发器;scheduler做为定时任务容器,是quartz最上层的东西,它提携了所有触发器和作业,使它们协调工作,每个scheduler都存有jobdetail和trigger的注册,一个scheduler中可以注册多个jobdetail和多个trigger。

1、job

      job是一个接口,只有一个方法void execute(jobexecutioncontext context),被调度的作业(类)需实现该接口中execute()方法,jobexecutioncontext类提供了调度上下文的各种信息。每次执行该job均重新创建一个job实例,如:

  1. public class ddnjob implements job{  
  2.   
  3.     public void execute(jobexecutioncontext arg0) throws jobexecutionexception {  
  4.         perform();  
  5.     }  
  6.       
  7.     public void perform(){ //执行报表统计入口函数    
  8.         //业务逻辑    
  9.                 system.out.println("自动ddn预授权开始执行-------------执行时间:"+new date());    
  10.         }    
  11. }  

注:ddnjob类为需要定时执行的类,execute为定时执行的方法。一个定时任务对应一个job实现类。

2、jobdetail

quartz在每次执行job时,都重新创建一个job实例,所以它不直接接受一个job的实例,相反它接收一个job实现类,以便运行时通过newinstance()的反射机制实例化job。因此需要通过一个类来描述job的实现类及其它相关的静态信息,如job名字、描述、关联监听器等信息,jobdetail承担了这一角色。jobdetail 用来保存我们作业的详细信息。一个jobdetail可以有多个trigger,但是一个trigger只能对应一个jobdetail,

示例:

  1.  jobdetail jobdetail = new jobdetail("myjob","mygroup",ddnjob.class)   
  2.  说明:    
  3.  myjob:job 名     
  4.   mygroup:job 组(为'null'时,使用缺省的组sched.default_group)     
  5.  ddnjob.class:要被执行的java类。 

运用spring集成的methodinvokingjobdetailfactorybean时spring能自动生成符合quartz要去的jobdetail。
spring中applicationcontext.xml配置如下:

  1. <!-- detail任务描述 -->   
  2.     <bean name="ddndetail"    
  3.         class="com.mangocity.mpm.common.autoddn.methodinvokingjobdetailfactorybean">    
  4.         <property name="targetobject" value="ddnjob" />  
  5.         <property name="concurrent" value="false"/>(并发执行)  
  6.         <property name="shouldrecover" value="true"/>    
  7.     </bean>    

3、trigger

trigger是一个类,描述触发job执行的时间触发规则。主要有simpletrigger和 crontrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,simpletrigger是最适合的选择;而crontrigger则 可以通过cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;spring中applicationcontext.xml配置如下:

simpletrigger使用示例

  1. <bean id="ddnsimpletrigger" class="org.springframework.scheduling.quartz.simpletriggerbean">  
  2.         <property name="jobdetail" ref="ddndetail"/>  
  3.         <property name="startdelay" value="1"/>  
  4.         <property name="repeatcount" value="100"/>   
  5.         <property name="repeatinterval" value="1000"/>  
  6. </bean>  

crontrigger使用示例

  1. // initiate crontrigger with its name and group name  
  2. crontrigger crontrigger = new crontrigger("crontrigger","triggergroup2");  
  3. try {  
  4.     // setup cronexpression  
  5.      cronexpression cexp = new cronexpression("0/5 * * * * ?");  
  6. // assign the cronexpression to crontrigger  
  7.      crontrigger.setcronexpression(cexp);  
  8. catch (exception e) {  
  9.        e.printstacktrace();  
  10. }  

通过spring配置,jobdetail为配置的job描述,cronexpression为job的运行规则,具体见附录部分内容。

  1. <bean id="ddncrontrigger" class="org.springframework.scheduling.quartz.crontriggerbean">  
  2.         <property name="jobdetail" ref="ddndetail"/>  
  3.         <property name="cronexpression" value="0/5 * * ? * * *"/>  
  4. </bean>      

4、scheduler

        scheduler负责管理quartz的运行环境,quartz它是基于多线程架构的,它启动的时候会初始化一套线程,这套线程会用来执行一些预置的作业。trigger和jobdetail可以注册到scheduler中;scheduler可以将trigger绑定到某一jobdetail中,这样当trigger触发时,对应的job就被执行。         scheduler拥有一个schedulercontext,它类似于servletcontext,保存着scheduler上下文信息,job和trigger都可以访问schedulercontext内的信息。scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。 应用示例:   

  1. schedulerfactory schedulerfactory = new stdschedulerfactory();  
  2.     // retrieve a scheduler from schedule factory  
  3.     scheduler scheduler = schedulerfactory.getscheduler();  
  4.      …  
  5.     // schedule a job with jobdetail and trigger  
  6.      scheduler.schedulejob(jobdetail, simpletrigger);  
  7.     // start the scheduler  
  8.     scheduler.start();  

spring中applicationcontext.xml配置:

  1. <!-- 调度器  -->    
  2.     <bean  class="org.springframework.scheduling.quartz.schedulerfactorybean">   
  3.         <property name="datasource">  
  4.             <ref bean="datasource"/>  
  5.         </property>   
  6.         <property name="triggers">    
  7.             <list>    
  8.                 <!--  触发器列表 -->    
  9.                 <!-- <ref bean="ddncrontrigger" />  -->  
  10. <ref bean="ddnsimpletrigger" />  
  11.             </list>    
  12.         </property>   
  13.         <property name="configlocation" value="classpath:quartz.properties" />  
  14.     </bean>  

其中,datasource为数据源配置,triggers为触发器列表配置,可以同时包含多个trigger,configlocation为quartz配置文件quartz.properties加载路径。

四、总结:

       我们不只有一种两种方法来实现我们的定时任务,就我知道的出了我们的quartz框架之外,我们spring也自己封装有自己的定时器,再加上各种开源的插件。那我工作的公司来说,我们用windows服务来完成这个定时任务,万变不离其宗,理解了他们的原理以及精髓,我们就可以去创新,去写出符合自己要求的工具了!