文档章节

Quartz 任务调度机制笔记——01

尤雪萍
 尤雪萍
发布于 2014/04/05 02:11
字数 1043
阅读 140
收藏 1

实例:

1、代码实现Demo

@Test

    public void demo01() throws InterruptedException{

       //获取调度器

       SchedulerFactory schedulerFactory = new StdSchedulerFactory();

       Scheduler scheduler = null;

       try {

           scheduler = StdSchedulerFactory.getDefaultScheduler();

          

           //引进作业程序这,里的HelloJob是一个Job的继承类,重载的excute方法

           JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)

                                           .withIdentity("helloJob", "group01" )

                                           .build();

           //生成一个触发器,这里这个SimpleTriggerImpl可以被其他的Trigger替换掉的

           SimpleTriggerImpl simpleTriggerImpl = new SimpleTriggerImpl( "trigger", "group01" );

          //我使用的是:

           //Trigger simpleTriggerImpl = TriggerBuilder.newTrigger().withIdentity("trigger", "group01").build();

           simpleTriggerImpl.setStartTime( new Date(System.currentTimeMillis()));

          

           simpleTriggerImpl.setRepeatInterval(2000);

           simpleTriggerImpl.setRepeatCount(10);

          

           //作业和触发器设置到调度器中

           scheduler.scheduleJob(jobDetail, simpleTriggerImpl);

           //启动调度器

           System. out.println(jobDetail.getKey().toString());

           scheduler.start();

   //注意,在Quartz中,这个调度器的生命周期是和主线程相关的,所有如果主线程退出了,那么调度器也就结束了

           Thread. sleep(20000);

        } catch (SchedulerException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }finally{

            System. out.println(HelloJob. count);

        }

    }


2、配置文件实现:Demo

quartz.properties


org.quartz.scheduler.instanceName = TestScheduler

org.quartz.scheduler.instanceId = one


org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount =  2

org.quartz.threadPool.threadPriority = 4


org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin

org.quartz.plugin.jobInitializer.fileNames = jobs.xml #自己的job配置文件

org.quartz.plugin.jobInitializer.failOnFileNotFound = true

org.quartz.plugin.jobInitializer.scanInterval = 10

org.quartz.plugin.jobInitializer.wrapInUserTransaction = false


jobs.xml


<?xml version='1.0' encoding= 'utf-8'?>

<job-scheduling-data xmlns= "http://www.quartz-scheduler.org/xml/JobSchedulingData"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData

                          http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd" version= "1.8">

  < schedule>

  < job>         

    <name >hello </name >

    <group >MYJOB_GROUP </group >

    <description >The job description </description >

    <job-class >com.qunar.xueping.HelloJob </job-class > ##这是为自己的job实现类

    <job-data-map > #设置JobDataMap key-value

      <entry >

          <key >key </key >

          <value >hotdog</value>

       </entry >

       <entry >

           <key >key2 </key >

           <value >ketchup, mayo</ value>

       </entry >

     </job-data-map >  

   </job >

     

    <trigger >     

     <simple >     

       <name >scanTrigger </name >     

       <group >DEFAULT </group >     

       <job-name >hello </job-name >     

       <job-group >MYJOB_GROUP </job-group >           

       <repeat-count >3 </repeat-count >     

       <repeat-interval >1000 </repeat-interval >     

     </simple >     

    </trigger >        

  </ schedule>

</job-scheduling-data>

注:具体的Schedule调度: 

scheduler = StdSchedulerFactory.getDefaultScheduler(); 

schedule.start();


进阶:


1、在调度器中表示一个job或者一个trigger的方式是通过一个JobKey来表示的,

JobKey jobKey = new JobKey("name" , "group");

Scheduler可以对job和Trigger进行一些操作


2、在进行任务调度过程中,可以通过JobDataMap来put Info到Job中去


3、通过SchedulerMetaData metaData = schedule.getMetaData(),里面有一些schedule的常见设置,例如threadPool的size,另外值得注意的是,metaData.getNumberOfJobsException()方法,这个方法返回的是当先执行了多少个job

(疑问:为什么我的Trigger的withRepeatCount设置的是10,但最终job的excute方法执行了11次)


4、注意Job的两个注释:@PersistJobDataAfterExecution @DisallowConcurrentExecution 做什么用,顾名思义啦


5、关于故障的恢复:

     在Quartz中对于故障的解决办法是将job persist到数据中,然后通过状态标识Recovering需要恢复的Job

          参考网站:http://ygydaiaq-gmail-com.iteye.com/blog/1729626

                                http://www.24xuexi.com/w/2011-04-16/88179.html

6、Listener:quartz有自己的监听器JobListener,TriggerListstener,SchedulerListerner

举例:JobListener:

public class MyJobListener implements JobListener{


    public String getName() {

        // TODO Auto-generated method stub

        return "MyJobListener";

    }

    public void jobToBeExecuted(JobExecutionContext context) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobToBeExecuted----");

    }


    public void jobExecutionVetoed(JobExecutionContext context) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobExecutionVetoed----");

    }


    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobWasExecuted----");

    }


}


设置Listener:

 @Test

    public void testJob03(){

        Scheduler scheduler  = null;

        try {

            scheduler = StdSchedulerFactory.getDefaultScheduler();

            scheduler.getListenerManager()

     .addJobListener(new MyJobListener() , KeyMatcher.keyEqualsnew JobKey("hello" , "MYJOB_GROUP")));

            scheduler.start();

            Thread. sleep(20000);

        } catch (Exception e) {

            // TODO: handle exception

            e.printStackTrace();

        }

    }

7、Quartz的故障恢复机制

默认情况下,Quartz中所提交的任务都是独立的运行在线程中,这意味着机器出现故障或任何原因导致这个线程被干掉了,那么提交的任务就无法继续也无法恢复

解决方法:在出现故障时将任务进行的状态保存下来,Quartz内置了数据库持久化的模块

配置文件:quartz.xml

#配置RAMJobStore

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore


#数据库配置

org.quartz.jobStore.misfireThreshold=60000

org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore


org.quartz.dataSource.DATA_SOURCE_NAME.driver=com.mysql.jdbc.Driver

org.quartz.dataSource.DATA_SOURCE_NAME.URL=jdbc:mysql://localhost:3306/ dbname

org.quartz.dataSource.DATA_SOURCE_NAME.user=root

org.quartz.dataSource.DATA_SOURCE_NAME.password= 12345

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

org.quartz.jobStore.dataSource=DATA_SOURCE_NAME


创建数据库:

导入quartz文档中的mysql.sql创建好需要的数据表


故障恢复Demo:

   @Test

   //@Ignore

    public void recovery() {

        Scheduler scheduler  = null;

        try {

            scheduler = StdSchedulerFactory.getDefaultScheduler();

            scheduler.getListenerManager()

     .addJobListener(new MyJobListener() , KeyMatcher.keyEqualsnew JobKey("hello" , "MYJOB_GROUP")));

            scheduler.start();

        //调用schedule的shutdown()方法,这个时候job还没有执行完成,所有会被记录到数据表qrtz_triggers中

            scheduler.shutdown();

        } catch (Exception e) {

            // TODO: handle exception

            e.printStackTrace();

        }


        try {

            //重新获取schedule调度器,值得注意的是这里获取的调度器同上面的调度器不是同一个对象,而是一个新的调度器

            scheduler = StdSchedulerFactory.getDefaultScheduler(); 

            scheduler.start();

        //得到group为TestDB的数据中的记录

            Set<TriggerKey> triggers = scheduler.getTriggerKeys(GroupMatcher.groupEquals ("TestDB" ));

            Iterator< TriggerKey> iterator = triggers.iterator();

            for (TriggerKey triggerKey : triggers) {

                Trigger trigger = scheduler.getTrigger(triggerKey);

//继续执行没执行完的trigger

                scheduler.rescheduleJob(triggerKey, trigger);

            }

            Thread. sleep(40000);

        } catch (SchedulerException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }



© 著作权归作者所有

尤雪萍
粉丝 2
博文 5
码字总数 3132
作品 0
北碚
程序员
私信 提问
基于spring+quartz的分布式任务调度

学习地址:http://www.roncoo.com/course/view/e2b459016e2e477dbd5d67c8b23fe86d 课程介绍 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相...

小红牛
2018/04/19
0
0
作业调度框架 Quartz 学习笔记(五) -- 错过的任务怎么办?

不知道大家在用Quartz的时候 有没有遇到这样一种情况: 触发器设定每3秒钟触发一次 ,但是工作需要10秒钟的执行时间.因此,在一次任务结束执行前,触发器已经错失触发 当这种情况下我们怎么处理...

哲别0
2017/10/24
101
0
Spring任务调度之Quartz集成

推荐一个博客:http://blog.csdn.net/column/details/14251.html 基本概念 Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobEx...

宇的季节
2017/12/17
0
0
定时任务工具——CronUtil

牢骚 Java中定时任务使用的最多的我想就是quartz了,但是这个框架太过庞大,而且我也不需要用到这么多东西,使用方法也是比较复杂(官方Demo我实在是无语……)。于是我便寻找新的框架代替(...

路小磊
2015/02/24
2.5K
6
(翻译)Quartz官方教程——第十一课:高级(企业)功能

集群 目前集群可以运行在JDBC-Jobstore (JobStoreTX o或者JobStoreCMT) 和TerracottaJobStore中。集群的特性包括负载均衡和故障转移(如果JobDetail的“request recovery”标识被设置为true)...

Iceberg_XTY
2018/04/23
24
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
7
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
7
0
Flutter系列之在 macOS 上安装和配置 Flutter 开发环境

本文为Flutter开发环境在macOS下安装全过程: 一、系统配置要求 想要安装并运行 Flutter,你的开发环境需要最低满足以下要求: 操作系统:macOS(64位) 磁盘空间:700 MB(不包含 IDE 或其余...

過愙
昨天
6
0
OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
昨天
2.6K
16
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
昨天
42
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部