Quartz框架(四)—misfire处理机制

Quartz框架(一)—Quartz的基本配置
Quartz框架(二)—jobstore数据库表字段详解
Quartz框架(三)—任务的并行/串行执行
Quartz框架(四)—misfire处理机制
Quartz框架(五)— 有状态的job和无状态job
Quartz框架(六)— Trigger状态转换
Quartz框架(七)— Quartz集群原理
Quartz框架(八)— Quartz实现异步通知
Quartz框架(九)— 动态操作Quartz定时任务
Quartz框架(十)监听

什么叫做misfire

在Quartz中,当一个持久化的触发器因为:
1. 调度器被关闭;
2. 线程池没有可用线程;
3. 项目重启;
4. 任务的串行执行;
而错过激活时间,就会发生激活失败(misfire)。

此时我们需要明确两个问题(1)如何判定激活失败;(2)如何处理激活失败;

1. 如何判定激活失败

Quartz框架(一)—Quartz的基本配置中,quartz.properties配置文件中含有一个属性是misfireThreshold(单位毫秒),用来指定调度引擎设置触发器超时的“临界值”。也就是说Quartz对于任务的超时是有容忍度的。只有超过这个容忍度才会判定位misfire。

quartz.properties的配置文件

#设置容忍度为12s
org.quartz.jobStore.misfireThreshold = 12000

Corn=[*/2 * * * * ?] 即每两秒循环一次

jobDetail每次执行需要7s

@Component
@DisallowConcurrentExecution
public class TestJob2 extends  CustomQuartzJobBean{
    private Logger logger = LoggerFactory.getLogger(TestJob2.class);

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        logger.info("【数据库配置定时】-【开始】");
        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("【数据库配置定时】-【结束】");
    }
}
任务编号 预定运行时刻 实际运行时刻 延迟量(秒)
1 17:54:00 17:54:00 0
2 17:54:02 17:54:07 5
3 17:54:04 17:54:14 10
4 17:54:06 17:54:21 misfire

从表中可以看到,每一次任务的延迟都是5s作用,该延迟量不断累积,并且与misfireThreshold比较,直到在17:54:21时发生了misfire,那么17:54:21第4次任务会不会执行呢,答案是不一定的,取决于配置。

2. 激活失败的处理

激活失败指令(Misfire Instruction[因死抓可神 指令])是触发器的一个重要配置。所有类型的触发器都有一个默认的指令:

Trigger.MISFIRE_INSTRUCTION_SMART_POLICY

但是这个“机智策略(policy [跑了谁] )”对于不同类型的触发器其具体行为是不同的。

misfire Instruction在qutz_triggers表中的字段。

misfire Instruction.png

代码中设置misfire策略的方式。

2.1 quartz中CornTrigger使用的策略

//所有的misfile任务马上执行
public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;
//在Trigger中默认选择MISFIRE_INSTRUCTION_FIRE_ONCE_NOW 策略
public static final int MISFIRE_INSTRUCTION_SMART_POLICY = 0;
// CornTrigger默认策略,合并部分misfire,正常执行下一个周期的任务。
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
//所有的misFire都不管,执行下一个周期的任务。
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
  • 可以通过setMisfireInstruction方法设置misfire策略。
 CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean();
 triggerFactoryBean.setName("corn_" + clazzName);
 triggerFactoryBean.setJobDetail(jobFactory.getObject());
 triggerFactoryBean.setCronExpression(quartzCorn);
 triggerFactoryBean.setGroup(QUARTZ_TRIGGER_GROUP);
 //设置misfire策略
 triggerFactoryBean.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY);
 triggerFactoryBean.afterPropertiesSet();
  • 也可以通过CronScheduleBuilder设置misfire策略。
 CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
 //MISFIRE_INSTRUCTION_DO_NOTHING
 csb.withMisfireHandlingInstructionDoNothing();
 //MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
 csb.withMisfireHandlingInstructionFireAndProceed();//(默认)
 //MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
 csb.withMisfireHandlingInstructionIgnoreMisfires();

策略的具体含义

前提:在每个星期周一下午5点到7点,每隔一个小时执行一次,理论上共执行3次。

1. 情景一:

//所有misfire的任务会马上执行
public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;

若是5点misfire,6:15系统恢复之后,5,6点的misfire会马上执行。

2. 情景二:

//不做任何事情
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;

若是5点misfire,6:15系统恢复之后,只会执行7点的misfire。如果下次执行时间超过了end time,实际上就没有执行机会了。

3. 情景三:(cronTrigger的默认策略)

// CornTrigger默认策略,合并部分misfire,正常执行下一个周期的任务。
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;

若是5点misfire,6:15系统恢复之后,立刻执行一次(只会一次)misfire。

2.2 quartz中SImpleTrigger使用的策略

  1. 若是使用MISFIRE_INSTRUCTION_SMART_POLICY—机智的策略

    • 如果Repeat=0; 【重复0次】
      instruction selected = MISFIRE_INSTRUCTION_FIRE_NOW;【立刻执行,对于不会重复执行的任务,只是默认的处理策略。】
    • 如果Repeat Count=REPEAT_INDEFINITELY;【无限重复】
      instruction selected = MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT;【在下一个激活点执行,且错过的执行机会作废。】
    • 如果Repeat Count>0;【有限重复】
      instruction selected = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT;【立即执行,并执行指定的次数。】

3. misfire的执行流程

  1. 若配置(默认为true,可配置)成获取锁前先检查是否有需要recovery的trigger,先获取misfireCount;
  2. 获取TRIGGER_ACCESS锁;
  3. misfired的判断依据:status=waiting,current_time-next_fire_time>misfireThreshold(可配置,默认1分钟)【即实际触发时间-预计触发时间大于容忍度时间】,获取misfired的trigger,默认一个事务中只能最大有20个misfired trigger(可配置)。
  4. updateAfterMisfired:获取misfired的策略(默认是MISFIRE_INSTRUCTION_SMART_POLICY该策略在CronTrigger中为MISFIRE_INSTRUCTION_FIRE_ONCE_NOW),根据策略更新nexFireTime。
  5. 将nextFireTime等更新到trigger表;
  6. commit connection,释放锁。
misfired执行流程

文章参考

Quartz的misfire处理机制分析

任务框架quartz的misfire理解

Quartz原理解密

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352