`
须等待
  • 浏览: 210754 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Quartz的故障恢复

阅读更多

     在默认的情况下,Quartz中所提交的任务都是独立的运行在内存中的线程,这意味着一旦机器出现故障或任何原因这个线程被干掉,那么提交的任务就无法继续也无法恢复。如果我们想要在系统出现故障的情况下恢复Quartz中的任务,就要把当前任务状态持久化,然后在系统恢复之后恢复任务的执行,这就是基本的解决思路。Quartz在这方面也提供了支持。

 

     首先,持久化的问题。要进行恢复就要将任务进行的状态保存下来,Quartz内置了数据库持久化的模块,我们要做的只是在配置文件中增加数据源,并在数据库中手动建好表就可以了。在%Quartz_HOME%/docs/dbTables目录下有大部分数据的建表语句,可以直接拿到数据库中进行建表操作。

 

 

org.quartz.jobStore.misfireThreshold=60000
org.quartz.dataSource.DATA_SOURCE_NAME.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.DATA_SOURCE_NAME.URL=jdbc:mysql://host:port/dbname
org.quartz.dataSource.DATA_SOURCE_NAME.user=root
org.quartz.dataSource.DATA_SOURCE_NAME.password=
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,就会发现提交的任务在相应的数据库表中可以找到,Quartz已经把任务的状态都记录下来了。

 

    剩下的恢复操作就很简单了,我们只要设置一个监听器(Tomcat、Spring中都有类似的模块,如果没有用到Tomcat、Spring的话也可以在自己的系统中设置启动的入口),在系统启动的时候去数据库中找到提交的任务,然后重新交给Quartz去管理就可以了。JobDetail类中有requestsRecovery属性,默认是false,当设置为true时,重新提交之后Quartz会检测当前的任务时候错过了应该触发的时间,如果错过了会立即触发一个任务。

 

    对于有状态的任务,如果需要保存任务中所传递的参数,则需要让工作类实现StateFulJob接口,这样Quartz在进行持久化的时候会把参数也保存下来,以便恢复。

 

    在系统启动的时候,启动quartz,quartz就会从数据库里恢复之前持久化的任务信息,错过触发时间,trigger有一系列的应对策略,这里在声明触发器的时候要设置好,如trigger.setMisfireInstruction(Trigger.INSTRUCTION_RE_EXECUTE_JOB);

 

public void recovery() {
        Scheduler scheduler = null;

        try {
            SchedulerFactory sf = new StdSchedulerFactory();
            scheduler = sf.getScheduler();

            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

 

 

 

PS: 评论里有同学说设置了requestsRecovery属性以后不需要重新提交,LZ作了 测试,确实是这样的,Quartz启动的时候会自动把持久化的任务提取出来执行,scheduler.rescheduleJob这个方法是用来以当前时间为基准来调整下一次触发的时间。如果没有调用这个方法的话,恢复的任务会假设自己处在系统退出前的时间,把错过的执行次数一次性全部执行一遍。

 

 

 

 

 

 

 

4
2
分享到:
评论
18 楼 须等待 2013-12-09  
heathcliffchen 写道
StdSchedulerFactory schFac = new StdSchedulerFactory();
Scheduler scheduler = schFac.getScheduler();
scheduler.start();

我按上面的写了后,为什么没见数据库的已有的任务自动开始调度

怎样在系统启动的时候去数据库中找到提交的任务,然后重新交给Quartz去管理?


配置文件里有一条是选择任务的持久化方式,这里要设置好quartz把任务持久化到数据库,你系统启动的时候启动quartz就会自动去数据库里把持久化的任务拿出来,该重跑的重跑,该调度的调度
17 楼 heathcliffchen 2013-12-09  
StdSchedulerFactory schFac = new StdSchedulerFactory();
Scheduler scheduler = schFac.getScheduler();
scheduler.start();

我按上面的写了后,为什么没见数据库的已有的任务自动开始调度

怎样在系统启动的时候去数据库中找到提交的任务,然后重新交给Quartz去管理?
16 楼 heathcliffchen 2013-12-09  
StdSchedulerFactory schFac = new StdSchedulerFactory();
Scheduler scheduler = schFac.getScheduler();
scheduler.start();

我按上面的写了后,为什么没见数据库的已有的任务自动开始调度
15 楼 须等待 2013-05-29  
liaochengfeng 写道
十分感谢, 关于次数计算, 我发现触发器每次的触发时间不那么准确,有时会有些偏差, 所以有点担心,以最后触发时间计算错过次数,会不那么准确


多线程环境下时间点误差是无法避免的额。。
14 楼 liaochengfeng 2013-05-29  
十分感谢, 关于次数计算, 我发现触发器每次的触发时间不那么准确,有时会有些偏差, 所以有点担心,以最后触发时间计算错过次数,会不那么准确
13 楼 须等待 2013-05-29  
liaochengfeng 写道
你好,我已配置好持久化,并设置了JobDetail的RequestsRecovery属性为true。
但是目前的现象是, 停机时错过多次任务的触发,但是重启后只恢复了一次。
请问,怎样才能达到 “把错过的执行次数一次性全部执行一遍。”呢?

谢谢了


我映像中quartz应该是在启动的时候检查数据库里持久化的任务发现错过了就执行,并不会去计算错过多少次,你可以在任务被触发的时候手动检查一下上次触发的时间,然后自己去计算错过了多少次,然后根据你自己的业务来手动触发任务
12 楼 liaochengfeng 2013-05-29  
你好,我已配置好持久化,并设置了JobDetail的RequestsRecovery属性为true。
但是目前的现象是, 停机时错过多次任务的触发,但是重启后只恢复了一次。
请问,怎样才能达到 “把错过的执行次数一次性全部执行一遍。”呢?

谢谢了
11 楼 Shen.Yiyang 2012-11-20  
须等待 写道
Shen.Yiyang 写道
须等待 写道
Shen.Yiyang 写道
如果你的job已经是requestsRecovery,难道quartz不会自动recover吗?还需要重新提交?

好吧,看来我之前的理解还是有偏差,我作了一些测试:即使没有requestsRecovery属性,只要配置了持久化信息,Quartz都会把Job的信息存如数据库,并且在启动的时候恢复数据库中的所有任务。

我说重新提交指的是scheduler.rescheduleJob(t, groupName, trigger);  方法,这个方法会以当前时间为基准调整下次触发的时间,不调用也可以恢复任务,但是这时恢复的任务会假设自己还是处在系统退出前的时间状态,会把错误的没有执行的次数一次性执行一遍。

  如果你的requestsRecovery是false,并且你没有rescheduleJob,难道quartz不会以现在为基准,去触发下一次?

不仅仅是触发下一次,是触发很多个下一次,执行(now-last)/period次

我这样问好了,如果没有reschedule,也没有requestsRecovery,但是job已经存在数据库了,服务器重启以后quartz会怎么运行,和你的reschedule有什么不同?
10 楼 须等待 2012-11-20  
Shen.Yiyang 写道
须等待 写道
Shen.Yiyang 写道
如果你的job已经是requestsRecovery,难道quartz不会自动recover吗?还需要重新提交?

好吧,看来我之前的理解还是有偏差,我作了一些测试:即使没有requestsRecovery属性,只要配置了持久化信息,Quartz都会把Job的信息存如数据库,并且在启动的时候恢复数据库中的所有任务。

我说重新提交指的是scheduler.rescheduleJob(t, groupName, trigger);  方法,这个方法会以当前时间为基准调整下次触发的时间,不调用也可以恢复任务,但是这时恢复的任务会假设自己还是处在系统退出前的时间状态,会把错误的没有执行的次数一次性执行一遍。

  如果你的requestsRecovery是false,并且你没有rescheduleJob,难道quartz不会以现在为基准,去触发下一次?

不仅仅是触发下一次,是触发很多个下一次,执行(now-last)/period次
9 楼 zhongliangjun1 2012-11-20  
hot66hot 写道
看看项目中使用Quartz集群分享.
传送门:http://hot66hot.iteye.com/blog/1726143

优质链接,马一个了~
8 楼 Shen.Yiyang 2012-11-20  
须等待 写道
Shen.Yiyang 写道
如果你的job已经是requestsRecovery,难道quartz不会自动recover吗?还需要重新提交?

好吧,看来我之前的理解还是有偏差,我作了一些测试:即使没有requestsRecovery属性,只要配置了持久化信息,Quartz都会把Job的信息存如数据库,并且在启动的时候恢复数据库中的所有任务。

我说重新提交指的是scheduler.rescheduleJob(t, groupName, trigger);  方法,这个方法会以当前时间为基准调整下次触发的时间,不调用也可以恢复任务,但是这时恢复的任务会假设自己还是处在系统退出前的时间状态,会把错误的没有执行的次数一次性执行一遍。

  如果你的requestsRecovery是false,并且你没有rescheduleJob,难道quartz不会以现在为基准,去触发下一次?
7 楼 须等待 2012-11-20  
coffeesweet 写道
呵呵,我觉得说的挺仔细的,算作自己学习的文章吧,挺好,一点一点慢慢积累。

6 楼 coffeesweet 2012-11-20  
呵呵,我觉得说的挺仔细的,算作自己学习的文章吧,挺好,一点一点慢慢积累。
5 楼 Bsklqgy 2012-11-20  
    
4 楼 须等待 2012-11-20  
Shen.Yiyang 写道
如果你的job已经是requestsRecovery,难道quartz不会自动recover吗?还需要重新提交?

好吧,看来我之前的理解还是有偏差,我作了一些测试:即使没有requestsRecovery属性,只要配置了持久化信息,Quartz都会把Job的信息存如数据库,并且在启动的时候恢复数据库中的所有任务。

我说重新提交指的是scheduler.rescheduleJob(t, groupName, trigger);  方法,这个方法会以当前时间为基准调整下次触发的时间,不调用也可以恢复任务,但是这时恢复的任务会假设自己还是处在系统退出前的时间状态,会把错误的没有执行的次数一次性执行一遍。
3 楼 freezingsky 2012-11-19  
我以为是讲什么新鲜的。
2 楼 hot66hot 2012-11-19  
看看项目中使用Quartz集群分享.
传送门:http://hot66hot.iteye.com/blog/1726143
1 楼 Shen.Yiyang 2012-11-19  
如果你的job已经是requestsRecovery,难道quartz不会自动recover吗?还需要重新提交?

相关推荐

    Spring Quartz 动态暂停、恢复、修改定时任务

    Spring Quartz 动态暂停、恢复、修改定时任务的一个demo,使用maven构建,框架采用spring springmvc jpa,数据库mysql,含数据库脚本,运行可用,页面访问地址http://localhost:8080/quartz_demo/quartz/list

    quartz指南,Quartz 工程

    文件里面包括 1:Quartz开发指南.pdf 2:Quartz从入门到进阶.pdf 3:QuartzBeginnerExample一个附带的工程例子 4:quartz-1.6.1.zip Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它...

    quartz简单实例quartz简单实例

    quartz简单实例quartz简单实例quartz简单实例quartz简单实例

    quartz-2.3.2-API文档-中文版.zip

    赠送jar包:quartz-2.3.2.jar; 赠送原API文档:quartz-2.3.2-javadoc.jar; 赠送源代码:quartz-2.3.2-sources.jar; 赠送Maven依赖信息文件:quartz-2.3.2.pom; 包含翻译后的API文档:quartz-2.3.2-javadoc-API...

    quartz-1.6.0.jar和quartz-all-1.6.0.jar

    该压缩包内包含两个quartz的jar包, 分别是quartz-1.6.0.jar和quartz-all-1.6.0.jar

    ssm整合quartz定时任务实现动态增删改查,暂停任务,恢复任务

    ssm整合quartz 并持久化到数据库中,实现动态增删改查,暂停任务,恢复任务等 将链接内的target文件直接放到项目ssmquartztest文件夹下 运行环境: jdk5+tomcat7+mysql+eclipse+maven lib jar包下载地址 地址1:...

    quartz-2.2.3版本的quartz初始化sql语句

    quartz-2.2.3版本的quartz初始化sql语句

    quartz-2.3.0-API文档-中文版.zip

    赠送jar包:quartz-2.3.0.jar; 赠送原API文档:quartz-2.3.0-javadoc.jar; 赠送源代码:quartz-2.3.0-sources.jar; 赠送Maven依赖信息文件:quartz-2.3.0.pom; 包含翻译后的API文档:quartz-2.3.0-javadoc-API...

    lucene与quartz例子

    lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子lucene quartz 例子

    quartz1.5,quartz1.6,quartz1.8

    Quartz1.5,Quartz1.6,Quartz1.8。Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个...

    quartz quartz-1.8.6 dbTables 建表sql

    quartz quartz-1.8.6 dbTables quartz动态任务调度需要的数据库脚本。

    Quartz介绍.docx

    Quartz使用方法Quartz使用方法Quartz使用方法Quartz使用方法Quartz使用方法

    Quartz.NET-2.0

    Quartz.NET框架的核心是调度器。调度器负责管理Quartz.NET应用运行时环境。Quartz不仅仅是线程和线程管理。为确保可伸缩性,Quartz.NET采用了基于多线程的架构。启动时,框架初始化一套worker线程,这套线程被调度器...

    quartz内部表.sql

    quartz内部表.sql。

    Quartz原理及实例

    Quartz原理及实例,spring4.x+Quartz.2.2.1结合的开发,静态和动态实例

    quartz 时间配置规则

    quartz 时间配置规则quartz 时间配置规则quartz 时间配置规则quartz 时间配置规则quartz 时间配置规则quartz 时间配置规则

    quartz实例,quartz入门例子

    在 myeclipse6.0.1下调试成功可直接运行的spring的quartz的例子,很适合刚接触quartz调度学习。

    Quartz-2.0.2 CSDN下载

    Quartz框架的核心是调度器。调度器负责管理Quartz应用运行时环境。调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。 Quartz不仅仅是线程和线程管理。为确保可伸缩性,Quartz采用了基于多线程的...

    quartz-2.2.1 最新包

    quartz-2.2.1 最新包

    Autofac.Extras.Quartz, Quartz.Net的Autofac集成.zip

    Autofac.Extras.Quartz, Quartz.Net的Autofac集成 Autofac.Extras.Quartz用于 Quartz.Net的Autofac集成包。Autofac.Extras.Quartz 为每个石英作业创建嵌套的litefime作用域。 完成作业执行后释放嵌套作用域。这允许...

Global site tag (gtag.js) - Google Analytics