定时任务调度框架Quartz--Misfire处理规则

2023-11-07 20:40

本文主要是介绍定时任务调度框架Quartz--Misfire处理规则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

          • SimpleTrigger
            • 结论
            • withMisfireHandlingInstructionIgnoreMisfires
            • withMisfireHandlingInstructionFireNow
            • withMisfireHandlingInstructionNowWithExistingCount
            • withMisfireHandlingInstructionNowWithRemainingCount
            • withMisfireHandlingInstructionNextWithRemainingCount
            • withMisfireHandlingInstructionNextWithExistingCount
          • CronTrigger
            • 结论
            • withMisfireHandlingInstructionIgnoreMisfires
            • withMisfireHandlingInstructionFireAndProceed
            • withMisfireHandlingInstructionDoNothing

纸上得来终觉浅,绝知此事要躬行。亲测得出的结论。

SimpleTrigger
结论
策略编码结论
withMisfireHandlingInstructionIgnoreMisfires-1IgnoreMisfires把所有错过的定时任务一次性执行。即使定时任务执行的时间已经结束,它也会把所有应该执行的任务一次性全部执行完。这个不是忽略已经错失的触发的意思,而是说忽略MisFire策略。它会在资源合适的时候,重新触发所有的MisFire任务,并且不会影响现有的调度时间
withMisfireHandlingInstructionFireNow1FireNow开发者希望只执行一次的定时任务使用FireNow这种策略。从执行效果上来看,如果该定时任务本该执行却因为种种原因没有执行,那么该策略在程序启动的时候会追回执行一次。即使结束时间已经过了,也会执行一次,坚持不懈的精神值得表扬
withMisfireHandlingInstructionNowWithExistingCount2NowWithExistingCount表示如果有任何一次错过的执行,那么在程序启动的时候会执行一次,然后继续按照正常的频率执行接下来的调度任务,直到程序结束。如果结束时间已经过了,则不会再执行
withMisfireHandlingInstructionNowWithRemainingCount3NowWithRemainingCount表示忽略已经错过的任务,以当前时间为触发起点立即触发执行,并按照正常的频率执行,直到任务时间结束。如果当前时间已经超过结束时间,则不会再执行
withMisfireHandlingInstructionNextWithRemainingCount4NextWithRemainingCount表示忽略已经错过的调度,按照正常频率执行下次定时任务,直到任务结束。如果已经超过结束时间,那么就不了了之,不再执行。综上,NextWithRemainingCount不触发立即执行——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
withMisfireHandlingInstructionNextWithExistingCount5NextWithRemainingCount几乎与withMisfireHandlingInstructionNextWithRemainingCount相同

         还有一个编码是0的,我就偷个懒了。从网上找了资料
在这里插入图片描述

withMisfireHandlingInstructionIgnoreMisfires
public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;

       IgnoreMisfires策略会把所有错过的定时任务一次性执行。即使定时任务执行的时间已经结束,它也会把所有应该执行的任务一次性全部执行完。这个不是忽略已经错失的触发的意思,而是说忽略MisFire策略。它会在资源合适的时候,重新触发所有的MisFire任务,并且不会影响现有的调度时间。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger5 = newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.todayAt(16, 0, 0)).withSchedule(simpleSchedule().withIntervalInMinutes(60).repeatForever()//把所有应该执行而没有执行的定时任务一次性全部执行.withMisfireHandlingInstructionIgnoreMisfires()               ).forJob("job1", "group1").endAt(DateBuilder.todayAt(18, 0, 0)).build();scheduler.scheduleJob(job, trigger5);//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是从16点开始执行定时任务,每个小时执行一次,直到18点。因为启动程序时间在17点50分,所以本应该执行16点一次任务,17点一次任务。

程序的运行结果表明,在启动之时立刻追加执行本该执行的2次打印任务。
在这里插入图片描述

withMisfireHandlingInstructionFireNow
public static final int MISFIRE_INSTRUCTION_FIRE_NOW = 1;

       FireNow这种策略从作者的注释描述来看,开发者希望只执行一次的定时任务使用FireNow这种策略。从执行效果上来看,如果该定时任务本该执行却因为种种原因没有执行,那么该策略在程序启动的时候会追回执行一次。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger = newTrigger().withIdentity("trigger1", "group1").usingJobData("格言2", "沉默是金2").startAt(DateBuilder.todayAt(19, 20, 20)).withSchedule(simpleSchedule().//立即执行错过的定时任务调度。这通常只适用于只执行一次的任务。           withMisfireHandlingInstructionFireNow()).forJob(job).build();scheduler.scheduleJob(job, trigger);//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的19点20分打印程序,但是程序启动却是在19点21分,所以立即根据FireNow 策略,执行19点20分错过的定时任务一次。

程序的运行结果表明,在程序启动之时立即执行在19点20分错过的定时任务。
在这里插入图片描述

withMisfireHandlingInstructionNowWithExistingCount
public static final int 
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2;

       NowWithExisingCount表示如果有任何一次错过的执行,那么在程序启动的时候会执行一次,然后继续按照正常的频率执行接下来的调度任务,直到程序结束。如果结束时间已经过了,则不会再执行。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger5 = newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.todayAt(19, 45, 0)).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10).withMisfireHandlingInstructionNowWithExistingCount()).forJob("job1", "group1").endAt(DateBuilder.todayAt(19, 48, 0)).build();scheduler.scheduleJob(job, trigger5 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的19点45分到48分执行,每10秒打印一次。但是程序启动却是在19点46分,所以说明有任务错过了,因此程序在启动的时候会执行一次,然后按照正常的频率每10秒执行一次。

在这里插入图片描述

withMisfireHandlingInstructionNowWithRemainingCount
public static final int 
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3;

       NowWithRemainingCount表示忽略已经错过的任务,以当前时间为触发起点立即触发执行,并按照正常的频率执行,直到任务时间结束。如果当前时间已经超过结束时间,则不会再执行。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger5 = newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.todayAt(9, 30, 0)).withSchedule(simpleSchedule().withIntervalInSeconds(10)//repeat forever.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)//忽略已经错过的任务,以当前时间为开始执行时间,按照频率正常执行.withMisfireHandlingInstructionNowWithRemainingCount()).forJob("job1", "group1").endAt(DateBuilder.todayAt(9, 40, 0)).build();scheduler.scheduleJob(job, trigger5 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的9点30分到40分执行,每10秒打印一次。但是程序启动却是在9点35分,所以说明有任务错过了。
NowWithRemainingCount表示忽略已经错过的任务,以当前时间为触发起点立即触发执行,并按照正常的频率执行,直到任务时间结束。
在这里插入图片描述

withMisfireHandlingInstructionNextWithRemainingCount
 public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4;

       NextWithRemainingCount表示忽略已经错过的调度,按照正常频率执行下次定时任务,直到任务结束。如果已经超过结束时间,那么就不了了之,不再执行。综上,NextWithRemainingCount不触发立即执行——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger5 = newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.todayAt(9, 50, 0)).withSchedule(simpleSchedule().withIntervalInSeconds(10)//repeat forever.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)//不触发立即执行——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数.withMisfireHandlingInstructionNextWithRemainingCount()).forJob("job1", "group1").endAt(DateBuilder.todayAt(9, 55, 0)).build();scheduler.scheduleJob(job, trigger5 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的9点50分到55分执行,每10秒打印一次。但是程序启动却是在9点52分,所以说明有任务错过了。

NextWithRemainingCount会按照执行正常频率的下次调度,所以从实际执行效果上看,执行的也都是分钟整点,印证了NextWithRemainingCount会等待下次触发频率周期时刻。
在这里插入图片描述

withMisfireHandlingInstructionNextWithExistingCount
public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5;

    几乎与上面的NextWithRemainingCount相同。

CronTrigger
结论
策略编码结论
withMisfireHandlingInstructionIgnoreMisfires-1IgnoreMisfires把所有错过的定时任务一次性执行。即使定时任务执行的时间已经结束,它也会把所有应该执行的任务一次性全部执行完。这个不是忽略已经错失的触发的意思,而是说忽略MisFire策略。它会在资源合适的时候,重新触发所有的MisFire任务,并且不会影响现有的调度时间
withMisfireHandlingInstructionFireAndProceed1MISFIRE_INSTRUCTION_FIRE_ONCE_NOW。如果有错过的任务,在启动的时候执行一次任务,然后按照正常的调度继续执行。如果超过结束时间且有错过的任务,在启动的时候执行一次任务,然后就不再执行。
withMisfireHandlingInstructionDoNothing2MISFIRE_INSTRUCTION_DO_NOTHING。忽略所有错过的任务,按照正常的调度执行了。如果当前时间超过了结束时间,不做任何追加执行
withMisfireHandlingInstructionIgnoreMisfires
public static final int 
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY= -1;

       追加执行所有错过的定时任务。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger2 = newTrigger().withIdentity("trigger2", "group1").usingJobData("格言3", "奥特曼猪猪侠闪电小子葫芦娃").startAt(DateBuilder.todayAt(19,0,0)).withSchedule(cronSchedule("0 0/10 19 * * ?").withMisfireHandlingInstructionIgnoreMisfires()).forJob("job1", "group1").build();scheduler.scheduleJob(job, trigger2 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的19点00分开始,每10分钟打印一次。但是程序启动却是在19点29分,共错过3次打印,分别是19:00,19:10,19:20。

IgnoreMisfires执行所有错过的任务。如果程序说结束时间到19:29分,那么即使现在超过了19:29分,那么也是追加执行3次,亲测。在这里插入图片描述

withMisfireHandlingInstructionFireAndProceed
CronTrigger.java类中public static final int 
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;

如果有错过的任务,在启动的时候执行一次任务,然后按照正常的调度继续执行。如果超过结束时间且有错过的任务,在启动的时候执行一次任务,然后就不再执行。

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger2 = newTrigger().withIdentity("trigger2", "group1").usingJobData("格言3", "奥特曼猪猪侠闪电小子葫芦娃").startAt(DateBuilder.todayAt(19,0,0))//.endAt(DateBuilder.todayAt(19,29,0)).withSchedule(cronSchedule("0 0/1 19 * * ?").witMisfireHandlingInstructionFireAndProceed()).forJob("job1", "group1").build();scheduler.scheduleJob(job, trigger2 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的19点00分开始,每1分钟打印一次。但是程序启动却是在19点41分,共错过很多次打印。

FireAndProceed或者说FIRE_ONCE_NOW在启动的时候只追加执行了一次,然后就按照正常的调度执行了。如果当前时间超过了结束时间,也会追加执行一次,然后就不再执行任何任务。在这里插入图片描述

withMisfireHandlingInstructionDoNothing
CronTrigger.java类中public static final int 
MISFIRE_INSTRUCTION_DO_NOTHING= 2;

忽略所有错过的任务,在下次调度时正常执行。即对错过的任务不做任何处理

public static void main(String[] args) {try {//define the job and bind it to our HelloJob classScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.start();JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").usingJobData("格言", "市场最小阻力路线初现的关键时刻").build();Trigger trigger2 = newTrigger().withIdentity("trigger2", "group1").usingJobData("格言3", "奥特曼猪猪侠闪电小子葫芦娃").startAt(DateBuilder.todayAt(19,0,0)).withSchedule(cronSchedule("0 0/1 19 * * ?").withMisfireHandlingInstructionDoNothing()).forJob("job1", "group1").build();scheduler.scheduleJob(job, trigger2 );//在调用shutdown()之前,你需要给job的触发和执行预留一些时间,比如,你可以调用Thread.sleep(1000000000);scheduler.shutdown();} catch (Exception e) {LOGGER.error("an exception was occurred , caused by :{}", e.getMessage());}}public static class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {LOGGER.error("现在是:{},JobInstanceId:{}", DateTransformTools.dateToDateStr(new Date()), this.hashCode());}}

上述程序的目的是在今天的19点00分开始,每1分钟打印一次。但是程序启动却是在19点47分20秒,共错过很多次打印。

DoNothing会忽略所有错过的任务,按照正常的调度执行了。如果当前时间超过了结束时间,不做任何追加执行。
在这里插入图片描述

这篇关于定时任务调度框架Quartz--Misfire处理规则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/366172

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

Python实现自动化接收与处理手机验证码

《Python实现自动化接收与处理手机验证码》在移动互联网时代,短信验证码已成为身份验证、账号注册等环节的重要安全手段,本文将介绍如何利用Python实现验证码的自动接收,识别与转发,需要的可以参考下... 目录引言一、准备工作1.1 硬件与软件需求1.2 环境配置二、核心功能实现2.1 短信监听与获取2.

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详