Quartz的MisFire机制解析

    在上一篇《Quartz的负载均衡如何实现》文章中说过Quartz的线程模型,提到了MisFire任务是由MisfireHandler线程专门进行处理的,本文主要是来了解下该部分功能是如何实现的。

 

源码分析:

    MisfireHandler线程定义在JobStoreSupport类中,在初始化的时候会将自己注册到线程池中:

public void initialize() {
    ThreadExecutor executor = getThreadExecutor();
    executor.execute(MisfireHandler.this);
}

 

来看下它的run()方法:

主要分成三步:

  1. 获取Misfire的trigger
  2. 通知QuartzSchedulerThread触发这些trigger的执行
  3. sleep一段时间,目的是At least a short pause to help balance threads(暂时不太理解这句话的含义)

 

来分析下如何获取Misfire的trigger,核心是manager()方法中的doRecoverMisfires():

    countMisfiredTriggersInState()用于查看是否确实存在Misfire的job,避免数据库加锁这一操作。Misfire判断依据是:status = WAITING, next_fire_time < current_time - misfirethreshold(可配置,默认1min)。即默认情况下,如果超过了Trigger本应触发时间60s,这次Trigger便不会再进行恢复了!

    但是如果确实存在Misfire的job,则会调用recoverMisfiredJobs()方法中的doUpdateOfMisfiredTrigger()方法修改Misfire Trigger的next fired time ,然后通知任务选取线程去调度,对这些Trigger进行恢复,默认情况一次最多同时恢复20个Trigger(maxToRecoverAtATime参数控制)。

    核心是updateAfterMisfire()方法,内部根据程序选取的Misfire策略设置Trigger的setNextFireTime(cal)进行恢复,本文接下来会说明一些Misfire策略。

 

触发trigger执行的代码逻辑就比较简单了:

if (recoverMisfiredJobsResult.getProcessedMisfiredTriggerCount() > 0) {

    signalSchedulingChangeImmediately(recoverMisfiredJobsResult.getEarliestNewTime());

}

内部通过sigLock.notifyall(),唤醒QuartzSchedulerThread线程调度执行任务:

 

 

常用的MisFire策略:

介绍下SimpleScheduler一些常用的Misfire策略:

 

withMisfireHandlingInstructionIgnoreMisfires

所有MisFire的Trigger会马上执行

 

withMisfireHandlingInstructionFireNow(默认)

立即执行Trigger,该策略适用于只执行一次的Trigger

 

withMisfireHandlingInstructionNextWithExistingCount

下一次Trigger时间到的时候执行任务,总次数不变

 

withMisfireHandlingInstructionNextWithRemainingCount(默认)

下一次Trigger时间到的时候执行任务,起始次数清零,重新开始执行

 

withMisfireHandlingInstructionNowWithExistingCount(默认)

立即执行Trigger,循环开始周期以当前时间为基准,总次数不变

 

withMisfireHandlingInstructionNowWithRemainingCount

立即执行Trigger,循环开始周期以当前时间为基准,起始次数清零,重新开始执行

 

 

默认情况下,Quartz的Scheduler会根据Trigger的触发次数来选择不同的MisFire策略:

 

 

 

 

 

参考:

    https://www.cnblogs.com/skyLogin/p/6927629.html(Misfire策略)

    https://www.jianshu.com/p/6afa510fa2ff(Quartz源码阅读)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值