企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
>[info]misfire 概念提出的理由:到了任务触发时间点,但是任务没有被触发。 可能的原因如下: * 线程池满了,没有资源执行任务。 * 机器宕机。 * 代码的 BUG 导致的异常终止。 为了让任务在错过之后,还能正常的运行,Quartz 针对不同的触发器提供了各种的 misfire 策略。 [TOC] # 1. SimpleTrigger触发器的misfire策略 **1. withMisfireHandlingInstructionFireNow()** >[info]所有被错过的任务都会被重新执行。 ```java TriggerBuilder.newTrigger() //21:38 .startAt(startCl.getTime()) //21:40 .endAt(endCl.getTime()) .withSchedule( SimpleScheduleBuilder.simpleSchedule() .withMisfireHandlingInstructionFireNow() .withIntervalInSeconds(2) .repeatForever() ) //应该在 21:38 开始,但我在 21:39 才启动项目 //会将 21:39 之前被错过的所有任务执行完,然后再按照触发器的规则执行 ``` * 在`(21:38, 21:40)`区间内启动项目,所有之前被错过的任务都会重新被执行。 * 在`21:40`之后再启动项目,之前被错过的所有任务都不会再被执行了。 ``` /***** 打印日志如下 *****/ //先将错过的任务执行完成 21:39:07 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:39:07 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:39:07 ...job.GoogsJob : 任务ID: job-group1.goods-job3 //再按照触发器的规则正常执行 21:39:09 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:39:11 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:39:13 ...job.GoogsJob : 任务ID: job-group1.goods-job3 ``` 下面这些策略虽然与 withMisfireHandlingInstructionFireNow() 有一些差别,但我懒得计较,它们的规则都是一样的。 ``` withMisfireHandlingInstructionNextWithExistingCount() withMisfireHandlingInstructionNextWithRemainingCount() withMisfireHandlingInstructionNowWithExistingCount() withMisfireHandlingInstructionNowWithRemainingCount() ``` <br/> **2. withMisfireHandlingInstructionIgnoreMisfires()** >[info]所有被错过的任务都会被重新执行。 ```java TriggerBuilder.newTrigger() //21:00 .startAt(startCl.getTime()) //21:03 .endAt(endCl.getTime()) .withSchedule( SimpleScheduleBuilder.simpleSchedule() .withMisfireHandlingInstructionIgnoreMisfires() .withIntervalInSeconds(2) .repeatForever() ) //应该在 21:00 开始,但我在 21:01 才启动项目 //会将 21:01 之前被错过的所有任务执行完,然后再按照触发器的规则执行 ``` ``` /***** 打印日志如下 *****/ //先将错过的任务执行完成 21:01:12 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:01:12 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:01:12 ...job.GoogsJob : 任务ID: job-group1.goods-job3 //再按照触发器的规则正常执行 21:01:14 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:01:16 ...job.GoogsJob : 任务ID: job-group1.goods-job3 21:01:18 ...job.GoogsJob : 任务ID: job-group1.goods-job3 /上面的触发器虽然定在 21:03 结束,但 21:03 之后再启动项目, //之前被错过的所有任务也会被执行的 ``` <br/> # 2. CronTrigger触发器的misfire策略 **1. withMisfireHandlingInstructionIgnoreMisfires()** >[info]所有被错过的任务都会被重新执行。 ```java CronScheduleBuilder.cronSchedule("0/2 * * * * ?") .withMisfireHandlingInstructionIgnoreMisfires() ``` <br/> **2. withMisfireHandlingInstructionDoNothing()** >[info]所有被错过的任务都会被丢弃。 ```java CronScheduleBuilder.cronSchedule("0/2 * * * * ?") .withMisfireHandlingInstructionDoNothing() ``` <br/> **3. withMisfireHandlingInstructionFireAndProceed()** >[info]将部分被错过的任务合并在一起执行一次,然后再正常执行下一周期的任务。 >【默认的 misfire 策略】 ```java CronScheduleBuilder.cronSchedule("0/2 * * * * ?") .withMisfireHandlingInstructionFireAndProceed() ``` ``` //下面这些是被错过的任务 //注意看下面的日志打印时间,它们都是在 22 的时候打印的 //而触发器规定的是每 2s 打印一次 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:22 ...job.GoogsJob : 任务ID: job-group1.goods-job4 //当将部分的被错过的任务执行后,就会正常执行下一周期的任务了,即每 2s 执行一次 2023-04-12T20:28:24 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:26 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:28 ...job.GoogsJob : 任务ID: job-group1.goods-job4 2023-04-12T20:28:30 ...job.GoogsJob : 任务ID: job-group1.goods-job4 ```