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这个方法是用来以当前时间为基准来调整下一次触发的时间。如果没有调用这个方法的话,恢复的任务会假设自己处在系统退出前的时间,把错过的执行次数一次性全部执行一遍。

 

 

 

 

 

 

 

你可能感兴趣的:(Quartz,故障,恢复)