关闭

Quartz-错过触发机制

标签: quartz错过触发机制misfire
878人阅读 评论(0) 收藏 举报
分类:

概述

有的时候我们会遇到这样一种情况:

触发器设定每3秒钟触发一次 ,但是工作需要10秒钟的执行时间.因此,在一次任务结束执行前,触发器已经错失触发

当这种情况下我们怎么处理呢? 我们来看下Quartz给的官方Demo


示例

这里我们参照Quartz官方提供的示例5来演示下

job类:StatefulDumbJob.java

package com.xgj.quartz.quartzItself.misfire;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;

/**
 * 
 * 
 * @ClassName: StatefulDumbJob
 * 
 * @Description: 通过设置错失触发后的调度策略,来处理错过的任务.
 * 
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年11月14日 下午9:36:52
 */

// 在Job被执行结束后,将会更新JobDataMap,这样下次Job执行后就会使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行, 为了避免并发问题导致数据紊乱,建议这两个注解一起使用
@DisallowConcurrentExecution
public class StatefulDumbJob implements Job {

    // 静态常量,作为任务在调用间,保持数据的键(key)

    public static final String NUM_EXECUTIONS = "NumExecutions"; // 保存的计数每次递增1
    public static final String EXECUTION_DELAY = "ExecutionDelay"; // 任务在执行时,中间睡眠的时间。本例中睡眠时间过长导致了错失触发

    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss");
        String jobRunTime = dateFormat.format(new Date());

        System.err.println("---" + context.getJobDetail().getKey().getName()
                + " 在  : [" + jobRunTime + "] 执行了!!");

        // 任务执行计数 累加
        JobDataMap map = context.getJobDetail().getJobDataMap();
        int executeCount = 0;
        if (map.containsKey(NUM_EXECUTIONS)) {
            executeCount = map.getInt(NUM_EXECUTIONS);
        }
        executeCount++;
        map.put(NUM_EXECUTIONS, executeCount);

        // 睡眠时间: 由调度类重新设置值 ,本例为 睡眠10s
        long delay = 5000l;
        if (map.containsKey(EXECUTION_DELAY)) {
            delay = map.getLong(EXECUTION_DELAY);
        }

        try {
            Thread.sleep(delay);
        } catch (Exception ignore) {
        }

        // 睡眠醒来后,打印任务执行结束的信息
        System.err.println("  -" + context.getJobDetail().getKey().getName()
                + " 完成次数  : " + executeCount);

    }

}

调度类: MisfireExample.java

package com.xgj.quartz.quartzItself.misfire;

import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

public class MisfireExample {

    public void run() throws Exception {

        // 任务执行的时间 格式化
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss");

        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler sched = sf.getScheduler();
        System.out.println("--------------- 初始化 -------------------");

        // 下一个第15秒
        Date startTime = nextGivenSecondDate(null, 15);

        // statefulJob1 每3s运行一次,但它会延迟10s
        JobDetail job = newJob(StatefulDumbJob.class)
                .withIdentity("statefulJob1", "group1")
                .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L) // 设置参数:睡眠时间10s
                .build();
        SimpleTrigger trigger = newTrigger()
                .withIdentity("trigger1", "group1")
                .startAt(startTime)
                .withSchedule(
                        simpleSchedule().withIntervalInSeconds(3)
                                .repeatForever()).build();


        Date ft = sched.scheduleJob(job, trigger);
        System.out.println(job.getKey().getName() + " 将在: "
                + dateFormat.format(ft) + "  时运行.并且重复: "
                + trigger.getRepeatCount() + " 次, 每次间隔 "
                + trigger.getRepeatInterval() / 1000 + " 秒");

        // statefulJob2 将每3s运行一次 , 但它将延迟10s, 然后不断的迭代,
        // 与statefulJob1不同的是设置了错失触发后的调整策略
        job = newJob(StatefulDumbJob.class)
                .withIdentity("statefulJob2", "group1")
                .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 10000L)// 设置参数:睡眠时间
                                                                        // 10s
                .build();
        trigger = newTrigger()
                .withIdentity("trigger2", "group1")
                .startAt(startTime)
                .withSchedule(
                        simpleSchedule().withIntervalInSeconds(3)
                                .repeatForever()
                                // 设置错失触发后的调度策略
                                .withMisfireHandlingInstructionNowWithRemainingCount())
                .build();

        ft = sched.scheduleJob(job, trigger);
        System.out.println(job.getKey().getName() + " 将在: "
                + dateFormat.format(ft) + "  时运行.并且重复: "
                + trigger.getRepeatCount() + " 次, 每次间隔 "
                + trigger.getRepeatInterval() / 1000 + " 秒");

        System.out.println("------- 开始调度 (调用.start()方法) ----------------");
        sched.start();

        // 给任务留时间运行 600S
        Thread.sleep(600L * 1000L);

        sched.shutdown(true);
        System.out.println("------- 调度已关闭 ---------------------");

        // 显示一下 已经执行的任务信息
        SchedulerMetaData metaData = sched.getMetaData();
        System.out.println("~~~~~~~~~~  执行了 "
                + metaData.getNumberOfJobsExecuted() + " 个 jobs.");
    }



    public static void main(String[] args) throws Exception {
        MisfireExample misfireExample = new MisfireExample();
        misfireExample.run();
    }
}

运行结果

INFO  StdSchedulerFactory - Using default implementation for ThreadExecutor
INFO  SimpleThreadPool - Job execution threads will use class loader of thread: main
INFO  SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
INFO  QuartzScheduler - Quartz Scheduler v.2.2.3 created.
INFO  RAMJobStore - RAMJobStore initialized.
INFO  QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.2.3) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

INFO  StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
INFO  StdSchedulerFactory - Quartz scheduler version: 2.2.3
--------------- 初始化 -------------------
statefulJob1 将在: 2017-11-14 23:01:00  时运行.并且重复: -1 次, 每次间隔 3 秒
statefulJob2 将在: 2017-11-14 23:01:00  时运行.并且重复: -1 次, 每次间隔 3 秒
------- 开始调度 (调用.start()方法) ----------------
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
---statefulJob1 在  : [2017-11-14 23:01:00] 执行了!!
---statefulJob2 在  : [2017-11-14 23:01:00] 执行了!!
  -statefulJob1 完成次数  : 1
---statefulJob1 在  : [2017-11-14 23:01:10] 执行了!!
  -statefulJob2 完成次数  : 1
---statefulJob2 在  : [2017-11-14 23:01:10] 执行了!!
  -statefulJob1 完成次数  : 2
---statefulJob1 在  : [2017-11-14 23:01:20] 执行了!!
  -statefulJob2 完成次数  : 2
---statefulJob2 在  : [2017-11-14 23:01:20] 执行了!!
  -statefulJob1 完成次数  : 3
---statefulJob1 在  : [2017-11-14 23:01:30] 执行了!!
  -statefulJob2 完成次数  : 3
---statefulJob2 在  : [2017-11-14 23:01:30] 执行了!!
  -statefulJob1 完成次数  : 4
---statefulJob1 在  : [2017-11-14 23:01:40] 执行了!!
  -statefulJob2 完成次数  : 4
---statefulJob2 在  : [2017-11-14 23:01:40] 执行了!!
  -statefulJob1 完成次数  : 5
---statefulJob1 在  : [2017-11-14 23:01:50] 执行了!!
  -statefulJob2 完成次数  : 5
---statefulJob2 在  : [2017-11-14 23:01:50] 执行了!!
  -statefulJob1 完成次数  : 6
---statefulJob1 在  : [2017-11-14 23:02:00] 执行了!!
  -statefulJob2 完成次数  : 6
---statefulJob2 在  : [2017-11-14 23:02:00] 执行了!!
  -statefulJob1 完成次数  : 7
  -statefulJob2 完成次数  : 7
---statefulJob1 在  : [2017-11-14 23:02:10] 执行了!!
---statefulJob2 在  : [2017-11-14 23:02:10] 执行了!!
  -statefulJob1 完成次数  : 8
---statefulJob1 在  : [2017-11-14 23:02:20] 执行了!!
  -statefulJob2 完成次数  : 8
---statefulJob2 在  : [2017-11-14 23:02:20] 执行了!!
  -statefulJob1 完成次数  : 9
  -statefulJob2 完成次数  : 9
---statefulJob2 在  : [2017-11-14 23:02:30] 执行了!!
---statefulJob1 在  : [2017-11-14 23:02:33] 执行了!!
  -statefulJob2 完成次数  : 10
---statefulJob2 在  : [2017-11-14 23:02:40] 执行了!!
  -statefulJob1 完成次数  : 10
---statefulJob1 在  : [2017-11-14 23:02:43] 执行了!!
  -statefulJob2 完成次数  : 11
---statefulJob2 在  : [2017-11-14 23:02:50] 执行了!!
  -statefulJob1 完成次数  : 11
---statefulJob1 在  : [2017-11-14 23:02:53] 执行了!!
  -statefulJob2 完成次数  : 12
---statefulJob2 在  : [2017-11-14 23:03:00] 执行了!!
  -statefulJob1 完成次数  : 12
---statefulJob1 在  : [2017-11-14 23:03:03] 执行了!!
  -statefulJob2 完成次数  : 13
---statefulJob2 在  : [2017-11-14 23:03:10] 执行了!!
  -statefulJob1 完成次数  : 13
---statefulJob1 在  : [2017-11-14 23:03:13] 执行了!!
  -statefulJob2 完成次数  : 14
---statefulJob2 在  : [2017-11-14 23:03:20] 执行了!!
  -statefulJob1 完成次数  : 14
---statefulJob1 在  : [2017-11-14 23:03:23] 执行了!!
  -statefulJob2 完成次数  : 15
---statefulJob2 在  : [2017-11-14 23:03:30] 执行了!!
  -statefulJob1 完成次数  : 15
---statefulJob1 在  : [2017-11-14 23:03:33] 执行了!!
  -statefulJob2 完成次数  : 16
---statefulJob2 在  : [2017-11-14 23:03:40] 执行了!!
  -statefulJob1 完成次数  : 16
---statefulJob1 在  : [2017-11-14 23:03:43] 执行了!!
  -statefulJob2 完成次数  : 17
---statefulJob2 在  : [2017-11-14 23:03:50] 执行了!!
  -statefulJob1 完成次数  : 17
---statefulJob1 在  : [2017-11-14 23:03:53] 执行了!!
  -statefulJob2 完成次数  : 18
---statefulJob2 在  : [2017-11-14 23:04:00] 执行了!!
  -statefulJob1 完成次数  : 18
---statefulJob1 在  : [2017-11-14 23:04:06] 执行了!!
  -statefulJob2 完成次数  : 19
---statefulJob2 在  : [2017-11-14 23:04:10] 执行了!!
  -statefulJob1 完成次数  : 19
---statefulJob1 在  : [2017-11-14 23:04:16] 执行了!!
  -statefulJob2 完成次数  : 20
---statefulJob2 在  : [2017-11-14 23:04:20] 执行了!!
  -statefulJob1 完成次数  : 20
---statefulJob1 在  : [2017-11-14 23:04:26] 执行了!!
  -statefulJob2 完成次数  : 21
---statefulJob2 在  : [2017-11-14 23:04:30] 执行了!!
  -statefulJob1 完成次数  : 21
---statefulJob1 在  : [2017-11-14 23:04:36] 执行了!!
  -statefulJob2 完成次数  : 22
---statefulJob2 在  : [2017-11-14 23:04:40] 执行了!!
  -statefulJob1 完成次数  : 22
---statefulJob1 在  : [2017-11-14 23:04:46] 执行了!!
  -statefulJob2 完成次数  : 23
---statefulJob2 在  : [2017-11-14 23:04:50] 执行了!!
  -statefulJob1 完成次数  : 23
---statefulJob1 在  : [2017-11-14 23:04:56] 执行了!!
  -statefulJob2 完成次数  : 24
---statefulJob2 在  : [2017-11-14 23:05:00] 执行了!!
  -statefulJob1 完成次数  : 24
---statefulJob1 在  : [2017-11-14 23:05:06] 执行了!!
  -statefulJob2 完成次数  : 25
---statefulJob2 在  : [2017-11-14 23:05:10] 执行了!!
  -statefulJob1 完成次数  : 25
---statefulJob1 在  : [2017-11-14 23:05:16] 执行了!!
  -statefulJob2 完成次数  : 26
---statefulJob2 在  : [2017-11-14 23:05:20] 执行了!!
  -statefulJob1 完成次数  : 26
---statefulJob1 在  : [2017-11-14 23:05:26] 执行了!!
  -statefulJob2 完成次数  : 27
---statefulJob2 在  : [2017-11-14 23:05:30] 执行了!!
  -statefulJob1 完成次数  : 27
---statefulJob1 在  : [2017-11-14 23:05:39] 执行了!!
  -statefulJob2 完成次数  : 28
---statefulJob2 在  : [2017-11-14 23:05:40] 执行了!!
  -statefulJob1 完成次数  : 28
---statefulJob1 在  : [2017-11-14 23:05:49] 执行了!!
  -statefulJob2 完成次数  : 29
---statefulJob2 在  : [2017-11-14 23:05:50] 执行了!!
  -statefulJob1 完成次数  : 29
---statefulJob1 在  : [2017-11-14 23:05:59] 执行了!!
  -statefulJob2 完成次数  : 30
---statefulJob2 在  : [2017-11-14 23:06:00] 执行了!!
  -statefulJob1 完成次数  : 30
---statefulJob1 在  : [2017-11-14 23:06:09] 执行了!!
  -statefulJob2 完成次数  : 31
---statefulJob2 在  : [2017-11-14 23:06:10] 执行了!!
  -statefulJob1 完成次数  : 31
---statefulJob1 在  : [2017-11-14 23:06:19] 执行了!!
  -statefulJob2 完成次数  : 32
---statefulJob2 在  : [2017-11-14 23:06:20] 执行了!!
  -statefulJob1 完成次数  : 32
---statefulJob1 在  : [2017-11-14 23:06:29] 执行了!!
  -statefulJob2 完成次数  : 33
---statefulJob2 在  : [2017-11-14 23:06:30] 执行了!!
  -statefulJob1 完成次数  : 33
---statefulJob1 在  : [2017-11-14 23:06:39] 执行了!!
  -statefulJob2 完成次数  : 34
---statefulJob2 在  : [2017-11-14 23:06:40] 执行了!!
  -statefulJob1 完成次数  : 34
---statefulJob1 在  : [2017-11-14 23:06:49] 执行了!!
  -statefulJob2 完成次数  : 35
---statefulJob2 在  : [2017-11-14 23:06:50] 执行了!!
  -statefulJob1 完成次数  : 35
---statefulJob1 在  : [2017-11-14 23:06:59] 执行了!!
  -statefulJob2 完成次数  : 36
---statefulJob2 在  : [2017-11-14 23:07:00] 执行了!!
  -statefulJob1 完成次数  : 36
  -statefulJob2 完成次数  : 37
---statefulJob2 在  : [2017-11-14 23:07:10] 执行了!!
---statefulJob1 在  : [2017-11-14 23:07:12] 执行了!!
  -statefulJob2 完成次数  : 38
---statefulJob2 在  : [2017-11-14 23:07:20] 执行了!!
  -statefulJob1 完成次数  : 37
---statefulJob1 在  : [2017-11-14 23:07:22] 执行了!!
  -statefulJob2 完成次数  : 39
---statefulJob2 在  : [2017-11-14 23:07:30] 执行了!!
  -statefulJob1 完成次数  : 38
---statefulJob1 在  : [2017-11-14 23:07:32] 执行了!!
  -statefulJob2 完成次数  : 40
---statefulJob2 在  : [2017-11-14 23:07:40] 执行了!!
  -statefulJob1 完成次数  : 39
---statefulJob1 在  : [2017-11-14 23:07:42] 执行了!!
  -statefulJob2 完成次数  : 41
---statefulJob2 在  : [2017-11-14 23:07:50] 执行了!!
  -statefulJob1 完成次数  : 40
---statefulJob1 在  : [2017-11-14 23:07:52] 执行了!!
  -statefulJob2 完成次数  : 42
---statefulJob2 在  : [2017-11-14 23:08:00] 执行了!!
  -statefulJob1 完成次数  : 41
---statefulJob1 在  : [2017-11-14 23:08:02] 执行了!!
  -statefulJob2 完成次数  : 43
---statefulJob2 在  : [2017-11-14 23:08:10] 执行了!!
  -statefulJob1 完成次数  : 42
---statefulJob1 在  : [2017-11-14 23:08:12] 执行了!!
  -statefulJob2 完成次数  : 44
---statefulJob2 在  : [2017-11-14 23:08:20] 执行了!!
  -statefulJob1 完成次数  : 43
---statefulJob1 在  : [2017-11-14 23:08:22] 执行了!!
  -statefulJob2 完成次数  : 45
---statefulJob2 在  : [2017-11-14 23:08:30] 执行了!!
  -statefulJob1 完成次数  : 44
---statefulJob1 在  : [2017-11-14 23:08:32] 执行了!!
  -statefulJob2 完成次数  : 46
---statefulJob2 在  : [2017-11-14 23:08:40] 执行了!!
  -statefulJob1 完成次数  : 45
---statefulJob1 在  : [2017-11-14 23:08:45] 执行了!!
  -statefulJob2 完成次数  : 47
---statefulJob2 在  : [2017-11-14 23:08:50] 执行了!!
  -statefulJob1 完成次数  : 46
---statefulJob1 在  : [2017-11-14 23:08:55] 执行了!!
  -statefulJob2 完成次数  : 48
---statefulJob2 在  : [2017-11-14 23:09:00] 执行了!!
  -statefulJob1 完成次数  : 47
---statefulJob1 在  : [2017-11-14 23:09:05] 执行了!!
  -statefulJob2 完成次数  : 49
---statefulJob2 在  : [2017-11-14 23:09:10] 执行了!!
  -statefulJob1 完成次数  : 48
---statefulJob1 在  : [2017-11-14 23:09:15] 执行了!!
  -statefulJob2 完成次数  : 50
---statefulJob2 在  : [2017-11-14 23:09:20] 执行了!!
  -statefulJob1 完成次数  : 49
---statefulJob1 在  : [2017-11-14 23:09:25] 执行了!!
  -statefulJob2 完成次数  : 51
---statefulJob2 在  : [2017-11-14 23:09:30] 执行了!!
  -statefulJob1 完成次数  : 50
---statefulJob1 在  : [2017-11-14 23:09:35] 执行了!!
  -statefulJob2 完成次数  : 52
---statefulJob2 在  : [2017-11-14 23:09:40] 执行了!!
  -statefulJob1 完成次数  : 51
---statefulJob1 在  : [2017-11-14 23:09:45] 执行了!!
  -statefulJob2 完成次数  : 53
---statefulJob2 在  : [2017-11-14 23:09:50] 执行了!!
  -statefulJob1 完成次数  : 52
---statefulJob1 在  : [2017-11-14 23:09:55] 执行了!!
  -statefulJob2 完成次数  : 54
---statefulJob2 在  : [2017-11-14 23:10:00] 执行了!!
  -statefulJob1 完成次数  : 53
---statefulJob1 在  : [2017-11-14 23:10:05] 执行了!!
  -statefulJob2 完成次数  : 55
---statefulJob2 在  : [2017-11-14 23:10:10] 执行了!!
  -statefulJob1 完成次数  : 54
---statefulJob1 在  : [2017-11-14 23:10:18] 执行了!!
  -statefulJob2 完成次数  : 56
---statefulJob2 在  : [2017-11-14 23:10:20] 执行了!!
  -statefulJob1 完成次数  : 55
---statefulJob1 在  : [2017-11-14 23:10:28] 执行了!!
  -statefulJob2 完成次数  : 57
---statefulJob2 在  : [2017-11-14 23:10:30] 执行了!!
  -statefulJob1 完成次数  : 56
---statefulJob1 在  : [2017-11-14 23:10:38] 执行了!!
  -statefulJob2 完成次数  : 58
---statefulJob2 在  : [2017-11-14 23:10:40] 执行了!!
  -statefulJob1 完成次数  : 57
---statefulJob1 在  : [2017-11-14 23:10:48] 执行了!!
  -statefulJob2 完成次数  : 59
---statefulJob2 在  : [2017-11-14 23:10:50] 执行了!!
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.
  -statefulJob1 完成次数  : 58
  -statefulJob2 完成次数  : 60
INFO  QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.
------- 调度已关闭 ---------------------
~~~~~~~~~~  执行了 118 个 jobs.

示例解释

misfire – 指的是 错过了触发时间

这个示例中2个触发器具有相同的时间安排,相同的任务,触发器设定每3秒钟触发一次,但是工作需要10秒钟的执行时间,因此,在一次任务结束执行前,触发器已经错失触发(除非’错失触发时限’被设置为超过7秒)。

其中第二个任务设置自己的错失触发指示:.withMisfireHandlingInstructionNowWithRemainingCount()


结论

1. 我们这个示例中,触发的间隔被设置为3秒,但是由于任务体执行间睡眠10秒,导致了错失触发的产生。

2. 实际运行的效果,2个任务执行的间隔为10秒。

3. 由于丢失触发时,job2的策略是立即触发,而job1是等待下一次机会触发。所以job2会赶在job1的前头,最终运行次数大于job1。


Quartz 的 Misfire (错失)处理规则

调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则

CronTrigger

withMisfireHandlingInstructionDoNothing

  • 不触发立即执行
  • 等待下次Cron触发频率到达时刻开始按照Cron频率依次执行

withMisfireHandlingInstructionIgnoreMisfires

  • 以错过的第一个频率时间立刻开始执行
  • 重做错过的所有频率周期后
  • 当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行

withMisfireHandlingInstructionFireAndProceed

  • 以当前时间为触发频率立刻触发一次执行
  • 然后按照Cron频率依次执行

SimpleTrigger

withMisfireHandlingInstructionFireNow

  • 以当前时间为触发频率立即触发执行
  • 执行至FinalTIme的剩余周期次数
  • 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
  • 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

withMisfireHandlingInstructionIgnoreMisfires

  • 以错过的第一个频率时间立刻开始执行
  • 重做错过的所有频率周期
  • 当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率
  • 共执行RepeatCount+1次

withMisfireHandlingInstructionNextWithExistingCount

  • 不触发立即执行
  • 等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
  • 以startTime为基准计算周期频率,并得到FinalTime
  • 即使中间出现pause,resume以后保持FinalTime时间不变

withMisfireHandlingInstructionNowWithExistingCount

  • 以当前时间为触发频率立即触发执行
  • 执行至FinalTIme的剩余周期次数
  • 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
  • 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

withMisfireHandlingInstructionNextWithRemainingCount

  • 不触发立即执行
  • 等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
  • 以startTime为基准计算周期频率,并得到FinalTime
  • 即使中间出现pause,resume以后保持FinalTime时间不变

withMisfireHandlingInstructionNowWithRemainingCount

  • 以当前时间为触发频率立即触发执行
  • 执行至FinalTIme的剩余周期次数
  • 以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
  • 调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY

这个不是忽略已经错失的触发的意思,而是说忽略MisFire策略。它会在资源合适的时候,重新触发所有的MisFire任务,并且不会影响现有的调度时间。

比如,SimpleTrigger每15秒执行一次,而中间有5分钟时间它都MisFire了,一共错失了20个,5分钟后,假设资源充足了,并且任务允许并发,它会被一次性触发。

这个属性是所有Trigger都适用。


MISFIRE_INSTRUCTION_FIRE_NOW

忽略已经MisFire的任务,并且立即执行调度。这通常只适用于只执行一次的任务。

MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT

将startTime设置当前时间,立即重新调度任务,包括的MisFire的

MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT

类似MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT,区别在于会忽略已经MisFire的任务

MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

在下一次调度时间点,重新开始调度任务,包括的MisFire的

MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT

类似于MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT,区别在于会忽略已经MisFire的任务。

MISFIRE_INSTRUCTION_SMART_POLICY

所有的Trigger的MisFire默认值都是这个,大致意思是“把处理逻辑交给聪明的Quartz去决定”。

基本策略是,

如果是只执行一次的调度,使用MISFIRE_INSTRUCTION_FIRE_NOW

如果是无限次的调度(repeatCount是无限的),使用
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT

否则,使用
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT


示例源码

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

1
0
查看评论

作业调度框架 Quartz 学习笔记(四) -- 接收参数和维护状态

> 如果你想在 某个job执行的时候传入参数,参数在job执行过程中对参数有所修改,并且在job执行完毕后把参数返回 那么你需要学习一下现在的这个例子了,因为它正是你所想要的 ......   我的建议是先把代码运行起来看结果,然后再去看代码. 还是老套路,两个类 一个jo...
  • lnara
  • lnara
  • 2013-03-07 13:35
  • 17673

Quartz调度器开发指南

Quartz调度器开发指南         V 2.2.1   目录 使用Quartz API 实例化Scheduler 关键接口 Job和Trigger 使用Job和JobDetail Job和JobDetail ...
  • github_36429631
  • github_36429631
  • 2017-03-18 11:39
  • 456

Quartz-错过触发机制

概述 官方示例概述有的时候我们会遇到这样一种情况:触发器设定每3秒钟触发一次 ,但是工作需要10秒钟的执行时间.因此,在一次任务结束执行前,触发器已经错失触发当这种情况下我们怎么处理呢? 我们来看下Quartz给的官方Demo官方示例
  • yangshangwei
  • yangshangwei
  • 2017-11-15 12:18
  • 878

MyBatis+Spring在注解@Autowried后通过反射的方式调用方法获取注入的Service或DAO对象为空

最近在做一个定时读取数据的功能,我的想法是能够动态的添加定时任务而不用重启系统,在网上也借阅了很多文章,但是都不够完整,因此通过网上的借鉴我自己整理了一份代码,系统采用的是Spring Boot+MyBatis。       通过Spring实现定时...
  • u013050790
  • u013050790
  • 2017-04-25 14:10
  • 1009

Quartz入门实例5-处理因执行job超时而错过触发的job

例子将执行以下操作: 1/启动Quartz调度器 
  • a67474506
  • a67474506
  • 2014-07-31 16:57
  • 3600

作业调度框架 Quartz 学习笔记(五) -- 错过的任务怎么办?

2013-03-11 15:23 10050人阅读 评论(2) 收藏 举报 不知道大家在用Quartz的时候 有没有遇到这样一种情况: 触发器设定每3秒钟触发一次 ,但是工作需要10秒钟的执行时间.因此,在一次任务结束执行前,触发器已经错失触发 当这种情况下我们怎么处理呢,让我...
  • a351945755
  • a351945755
  • 2014-07-10 12:14
  • 907

quartz触发器失败策略

概念理解misfire顾名思义, 就是quartz在应该触发trigger的时候未能及时将其触发( 原因可能是线程池没有线程可用 ), 这将导致trigger的下次触发时间落在在当前时间之前, 那么按照正常的quartz调度流程, 该trigger就再没有机会被调度了. 由于一个调度器实例在每次调度...
  • BeardedJ
  • BeardedJ
  • 2015-11-06 16:26
  • 1323

Quartz 有状态的JobDataMap

Quartz,每次执行job,job永远是全新的对象,但是,如果job实现org.quartz.StatefulJob接口,而不是job接口. 此时JobDetail的JobDataMap将会共享一个对象。 注意: 当实现有状态接口,StatefulJob时,只有JobDetail的JobDa...
  • caomiao2006
  • caomiao2006
  • 2015-06-08 20:22
  • 965

Quartz任务调度机制

Quartz任务调度机制 1 概述 1.1 了解Quartz体系结构 Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类对重要的这些核心概念进行描述: ●Job:是一个接口,只有一个方法void...
  • u011645059
  • u011645059
  • 2014-03-17 14:05
  • 847

Quartz 实现机制

quartz 是目前使用较广的调度管理工具,提供了与Linux下Cron类似的功能,实际上还更强大,可以方便的嵌入到Java系统中,最近就这个调度工具进行了一些简单的研究,主要研究调度后台的机制,quartz中包括的分布式调度和基于数据库的记录不在此处的研究范围,记录在这里方便以后回顾 quartz...
  • u010552936
  • u010552936
  • 2013-12-17 18:16
  • 819
    个人资料
    • 访问:1303432次
    • 积分:18978
    • 等级:
    • 排名:第558名
    • 原创:459篇
    • 转载:0篇
    • 译文:5篇
    • 评论:149条
    WeChat
      欢迎关注我的公众号,干货只有干货,还有更多惊喜和资源在等着你
    博客专栏