调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则
misfire产生的条件是:到了该触发执行时上一个执行还未完成,且线程池中没有空闲线程可以使用(或有空闲线程可以使用但job设置为@DisallowConcurrentExecution)且过期时间已经超过misfireThreshold就认为是misfire了,错失触发了

比如:13:07:24开始执行,重复执行5次,开始执行时,quartz已经计算好每次调度的时间刻,分别如下:

03:33:36,03:33:39,03:33:42,03:33:45,03:33:48,03:33:51

如果第一次执行时间为11s,到03:33:47结束,03:33:47减去03:33:39的时间间隔是8s,如果misfireThreshold设置的时间小于等于8s间隔,则认为是misfire了,如果大于8s间隔,则认为没有misfire。

CronTrigger

CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");csb.withMisfireHandlingInstructionDoNothing();
csb.withMisfireHandlingInstructionFireAndProceed();(默认)
csb.withMisfireHandlingInstructionIgnoreMisfires();
withMisfireHandlingInstructionDoNothing
——不触发立即执行
——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期后
——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行
withMisfireHandlingInstructionFireAndProceed(默认)
——以当前时间为触发频率立刻触发一次执行
——然后按照Cron频率依次执行

SimpleTrigger

SimpleScheduleBuilder ssb = SimpleScheduleBuilder.simpleSchedule();ssb.withMisfireHandlingInstructionFireNow();
ssb.withMisfireHandlingInstructionIgnoreMisfires();
ssb.withMisfireHandlingInstructionNextWithExistingCount();
ssb.withMisfireHandlingInstructionNextWithRemainingCount();
ssb.withMisfireHandlingInstructionNowWithExistingCount();  (默认)
ssb.withMisfireHandlingInstructionNowWithRemainingCount();
withMisfireHandlingInstructionFireNow
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
withMisfireHandlingInstructionIgnoreMisfires
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期
——当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率
——共执行RepeatCount+1次
withMisfireHandlingInstructionNextWithExistingCount
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
withMisfireHandlingInstructionNextWithRemainingCount
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
withMisfireHandlingInstructionNowWithExistingCount(默认)
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
withMisfireHandlingInstructionNowWithRemainingCount
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
——此指令导致trigger忘记原始设置的starttime和repeat-count
——触发器的repeat-count将被设置为剩余的次数
——这样会导致后面无法获得原始设定的starttime和repeat-count值

misfireHandler线程

下面这些原因可能造成 misfired job:

  1. 系统因为某些原因被重启。在系统关闭到重新启动之间的一段时间里,可能有些任务会被 misfire;
  2. Trigger 被暂停(suspend)的一段时间里,有些任务可能会被 misfire;
  3. 线程池中所有线程都被占用,导致任务无法被触发执行,造成 misfire;
  4. 有状态任务在下次触发时间到达时,上次执行还没有结束;为了处理 misfired job,Quartz 中为 trigger 定义了处理策略,主要有下面两种:MISFIRE_INSTRUCTION_FIRE_ONCE_NOW:针对 misfired job 马上执行一次;MISFIRE_INSTRUCTION_DO_NOTHING:忽略 misfired job,等待下次触发;默认是MISFIRE_INSTRUCTION_SMART_POLICY,该策略在CronTrigger中=MISFIRE_INSTRUCTION_FIRE_ONCE_NOW线程默认1分钟执行一次;在一个事务中,默认一次最多recovery 20个;

执行流程:

  1. 若配置(默认为true,可配置)成获取锁前先检查是否有需要recovery的trigger,先获取misfireCount;
  2. 获取TRIGGER_ACCESS锁;
  3. hasMisfiredTriggersInState:获取misfired的trigger,默认一个事务里只能最大20个misfired trigger(可配置),misfired判断依据:status=waiting,next_fire_time < current_time-misfirethreshold(可配置,默认1min)
  4. notifyTriggerListenersMisfired
  5. updateAfterMisfire:获取misfire策略(默认是MISFIRE_INSTRUCTION_SMART_POLICY,该策略在CronTrigger中=MISFIRE_INSTRUCTION_FIRE_ONCE_NOW),根据策略更新nextFireTime;
  6. 将nextFireTime等更新到trigger表;
  7. commit connection,释放锁
  8. 如果还有更多的misfired,sleep短暂时间(为了集群负载均衡),否则sleep misfirethreshold时间,后继续轮询;

misfireHandler线程执行流程如下图所示:

quartz-misfire 错失、补偿执行相关推荐

  1. Quartz 在misfire模式[错失、补偿执行] 策略

    概述 调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 misfire产生的条件是:到了该触发执行时上一个执行还未完成,且 ...

  2. quartz定时任务突然不执行了

    高并发情况下,quartz定时任务突然不执行了, 背景: 整个项目架构,高并发操作比较多, 有多个线程池,周期线程池,和定时任务,占用多个资源 导致现场出现定时任务走一段时间就不走的情况 当前定时任务 ...

  3. springboot 集成Quartz实现任务延迟执行和定时执行功能

    废话不多说了,直接上代码: 1.项目结构图 2.在application.yml配置文件中加入下面配置: quartz:#相关属性配置properties:org:quartz:scheduler:i ...

  4. quartz 每30秒执行一次_Net Core 使用 Quartz

    Net Core 使用 Quartz 复杂的业务系统经常伴随各种统计作业,许多会定时在深夜时间执行,Quartz是一套开源的作业调度框架,比较适合日常系统各种业务的定时处理 首先创建一个控制台应用程序 ...

  5. java定时执行sql语句_spring中使用quartz动态添加定时任务执行sql

    系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...

  6. java quartz web.xml_quartz定时执行任务,并配置web.xml的操作方法

    今天项目上需要做个定时任务,临时学的,quartz的功能还是很强大用起来也方便,这里的demo只是实现每天定时执行一次,其他功能可以在此基础上继续深入学习,哈哈 睡觉,明天继续. 一.maven依赖: ...

  7. quartz获取定时任务下次执行的时间

    quartz很多人都会用,但需要配置cronExpression. 这个cronExpression很多技术人员都要配置,但很多情况,我们要知道这个cronExpression下次执行的时间是啥,让非 ...

  8. quartz 每30秒执行一次_作业调度框架 Quartz 学习笔记(三) -- Cron表达式

    前面两篇说的是简单的触发器(SimpleTrigger) , SimpleTrigger 只能处理简单的事件出发,如果想灵活的进行任务的触发,就要请出 CronTrigger 这个重要人物了. Cro ...

  9. java 调度任务_Java Quartz 任务指定时间执行,任务调度框架

    quartz,spring-quartz,spring-task,spring-schedule四者的区别: quartz 是一个调度器,可以放任务进去,对任务指定时间执行. spring-quart ...

最新文章

  1. python数据可视化利用_利用pyecharts实现python数据可视化
  2. 主流机器学习[xgb, lgb, Keras, LR]
  3. sql server行级锁,排它锁,共享锁的使用
  4. 统计学习方法|支持向量机(SVM)原理剖析及实现
  5. 常见算法:C语言求最小公倍数和最大公约数三种算法
  6. Java多线程(1)
  7. java打包维护_java打包详解
  8. 1x1 11b g n linux,基于RN1810下的2.4 GHz IEEE 802.11b/g/n无线模块
  9. r语言 c语言调用函数返回值,r语言中怎样查看函数源代码
  10. 防盗链python_python一行代码,实现网页视频下载
  11. 首轮超巨诞生!利拉德轰50分送超远三分压哨绝杀 开拓者4-1淘汰雷霆
  12. 排序数组中的两个数字之和
  13. Electron 遭封杀,Web 开发者在苹果平台上举步维艰!
  14. Git教程_2 所有操作讲解
  15. 这几个5.20表白代码发给你女神,还没有女朋友直接来找我!
  16. 黑苹果OC引导注入声卡ID教程,解决开机无声音等问题
  17. python 实现图像的手绘效果
  18. js用blob下载pdf文件打开后中文乱码
  19. SEM数据分析之做好关键词报告
  20. SkyEye硬件模拟平台

热门文章

  1. MySQL 之视图、 触发器、事务、存储过程、内置函数、流程控制、索引(一)
  2. 5.Java中的常量以及常量的分类
  3. MongoDB数据库(8.Python中使用mongodb数据库以及pymongo模块用法)
  4. 离散蚁群算法实例(求解旅行商问题)
  5. opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测
  6. VTK:图像迭代器用法实战
  7. OpenCASCADE绘制测试线束:数据交换命令之XDE 图层命令
  8. OpenCASCADE:简介
  9. Boost.Signals2 的多槽 hello world 示例
  10. boost::hana::min用法的测试程序