第七节:Trigger(SimpleTrigger、CronTrigger)哑火(MisFire)策略 :
一. 简介
1. 什么是哑火
由于某些原因导致触发器(trigger)在该触发的时候没有得到触发,后续对应的解决策略即为哑火策略。(个人理解)
2. 哑火触发的条件
①:所有的工作线程都在忙碌,导致某些trigger得不到触发.(如:simplethreadpool 默认是10个工作线程,但我有15个trigger同时触发, 恰巧这10个trigger关联的job耗时都很长,剩下的5个trigger超过了等待时间仍然没有得到触发)
②:调度器(sheduler)中途挂了,某个时间又恢复了
③:设置的trigger的开始时间早于当前时间
如果没有触发哑火的条件,则不会触发哑火策略,之前的全部都是按照忽略来计算的,后续按照正常规律来进行。如果不设置开始时间,即为当前时间开始,不触发哑火策略。
下面介绍两类Trigger对应的哑火策略:SimpleTrigger和CronTrigger (前提:案例设置时间早于当前时间的,即都是有错过的)
二. SimpleTrigger哑火策略详解
这里要分三种情况来讨论,执行指定次数的情况WithRepeatCount(n),n=1、n>1、n=forever三种情况,重点理解n>1的情况,另外两种都是他的特殊情况而已。
(一):执行指定次数的情况(WithRepeatCount(n) n>1) 只要记住这种情况,下面的B和C都能分析出来
(1).默认 :立即执行,修改当前调度时间,总数保持不变 (等价于WithMisfireHandlingInstructionNowWithExistingCount)
详见下面解析
(2).WithMisfireHandlingInstructionIgnoreMisfires:错过的立即追赶,然后正常调度。
PS:设置的时间早于当前时间,执行的时候,会将当前时间之前错过的次数一次性执行完,然后正常按照设置的开始时间及规律进行执行。 如果设置的RepeatCount(n)中n的次数小于错过的次数,只能执行n次,执行完后,将不会在执行了,因为执行次数已经用完了。
案例:设置的开始时间为8:00,每隔半小时执行一次,执行总次数为5次,当前时间为9:05,那么开始时候会先执行3次,将错过的一次性执行了,然后按照正常调度执行,下一次执行的时间为9:30,还能执行两次。
(3).WithMisfireHandlingInstructionNextWithExistingCount:错过的不管了,按计划等待下次调度,总数不变,结束时间推迟。
PS:错过的次数不处理,仍按照设置的规律来执行,执行次数不变,要执行完的RepeatCount(n)中的n.
案例:设置的开始时间为8:00,每隔半小时执行一次,执行总次数为5次,当前时间为9:05,那么开始时候并没有调度执行,第一次执行调度的时间为9:30,然后按照正常调度执行,总共执行5次,最后一次时间为11:30。
(4).WithMisfireHandlingInstructionNextWithRemainingCount:错过的不管了,按计划等待下次调度,但总数要减去misfire错过的次数
PS:错过的次数不处理,仍按照设置的规律来执行,执行总数要 减去 错过的次数!
案例:设置的开始时间为8:00,每隔半小时执行一次,执行总次数为5次,当前时间为9:05,那么开始时候并没有调度执行,第一次执行调度的时间为9:30,然后按照正常调度执行,总共执行 5-3=2 次,最后一次时间为10:00。
(5).WithMisfireHandlingInstructionNowWithExistingCount: 立即执行,修改当前调度时间,总数保持不变
PS:立即执行,修改当前调度时间的含义为,即使我设置的开始时间早于当前时间,但该哑火策略会立马执行该触发器,即运行后,马上执行了一次,后续的时间间隔均是是以当前执行时间为基础来进行的,言外之意,之前设置的开始时间没用了,执行总数不变。
案例:设置的开始时间为8:00,每隔半小时执行一次,执行总次数为5次,当前时间为9:05,那么开始时候立即执行,第一次执行调度的时间为9:05,然后以9:05为基础,按照正常调度规律执行,总共执行5次,第二次时间为9:35,最后一次执行时间为11:05。
(6).WithMisfireHandlingInstructionNowWithRemainingCount: 立即执行,修改当前调度时间,总数要减去misfire错过的次数
PS:立即执行,修改当前调度时间的含义为,即使我设置的开始时间早于当前时间,但该哑火策略会立马执行该触发器,即运行后,马上执行了一次,后续的时间间隔均是是以当前执行时间为基础来进行的,言外之意,之前设置的开始时间没用了。执行总数要 减去 错过的次数!
案例:设置的开始时间为8:00,每隔半小时执行一次,执行总次数为5次,当前时间为9:05,那么开始时候立即执行,第一次执行调度的时间为9:05,然后以9:05为基础,按照正常调度规律执行,总共执行 5-3=2 次,第二次(即最后一次)时间为9:35。
B:只执行一次的情况 (WithRepeatCount(n) n=1) 对A情况的一个特殊分析
(1). 默认:(等价于WithMisfireHandlingInstructionFireNow)
(2). WithMisfireHandlingInstructionFireNow:立即执行
PS:设置的时间早于当前时间,执行的时候,立即把这一次执行完,后续将不再执行;但设置的时间晚于当前时间,则按照正常规律进行执行了
(3).WithMisfireHandlingInstructionNextWithRemainingCount 和 WithMisfireHandlingInstructionNowWithRemainingCount :不执行了
PS:设置的时间早于当前时间,执行的时候按照原规律执行,但是次数要减去错过的次数,这里总共就执行一次,所以就不执行了
C:永久执行的情况(RepeatForever) 对A情况的一个特殊分析
(1). 默认:等价与下面的(2),按计划的正常调度执行,执行次数永久执行
(2). WithMisfireHandlingInstructionNextWithExistingCount 和 WithMisfireHandlingInstructionNextWithRemainingCount:按计划的正常调度执行,执行次数永久执行
(3). WithMisfireHandlingInstructionNowWithExistingCount 和 WithMisfireHandlingInstructionNowWithRemainingCount: 立即执行,执行的开始时间改为当前时间,执行次数永久执行
代码分享:自行替换即可
public static void misfireShow()
{
//1.创建Schedule
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
//2.创建job (具体的job需要单独在一个文件中执行)
var job = JobBuilder.Create<HelloJob4>().Build();
//3.配置trigger
//下面的四个触发器对应了上面四种情况的测试,时间需要根据实际情况进行配置测试来设置
var trigger1 = TriggerBuilder.Create().StartAt(DateBuilder.DateOf(, , ))
.WithSimpleSchedule(x => x.WithIntervalInMinutes()
.WithRepeatCount()
.WithMisfireHandlingInstructionNowWithExistingCount()
).Build();
var trigger2 = TriggerBuilder.Create().StartAt(DateBuilder.DateOf(, , ))
.WithSimpleSchedule(x => x.WithIntervalInSeconds()
.WithRepeatCount()
.WithMisfireHandlingInstructionFireNow()
).Build();
var trigger3 = TriggerBuilder.Create()
.StartAt(DateBuilder.DateOf(, , , , , ))
.WithSimpleSchedule(x => x.WithIntervalInMinutes()
.WithMisfireHandlingInstructionNowWithRemainingCount()
.RepeatForever()).Build();
var trigger4 = TriggerBuilder.Create()
.StartAt(DateBuilder.DateOf(, , ))
.WithCronSchedule("0 0-59 9-23 ? * MON-FRI",x=>x.WithMisfireHandlingInstructionIgnoreMisfires()).Build(); //4.开始调度
scheduler.ScheduleJob(job, trigger1);
scheduler.Start();
}
三. CronTrigger哑火策略详解
(1). 默认:错过的合并,于当前时间执行一次,不修改调度时间,按计划等待下一次调度(等价于下面的 WithMisfireHandlingInstructionFireAndProceed)
(2). WithMisfireHandlingInstructionIgnoreMisfires:错过的立即追赶,然后正常调度
ps:错过多少次,初次执行的时候追赶多少次,追赶的次数的时间是按原规律执行的时间,然后按照原规律进行正常后续调度
(3). WithMisfireHandlingInstructionFireAndProceed:错过的合并,于当前时间执行一次,不修改调度时间,按计划等待下一次调度
PS:无论错过多少次,均在初次运行的时候,即当前时间执行一次,后续的执行仍按照原规律进行执行。
(4). WithMisfireHandlingInstructionDoNothing:错过的不管了,后续按照正常调度进行
PS:无论错过多少次,均忽略,后续的执行仍按照原规律进行执行。
代码详见上面的代码分享

第七节:Trigger(SimpleTrigger、CronTrigger)哑火(MisFire)策略 :的更多相关文章
- 浅谈Trigger(SimpleTrigger&CronTrigger)
1.Trigger是什么 Quartz中的触发器用来告诉调度程序作业什么时候触发,即Trigger对象是用来触发执行job的. 2.Quartz中的Trigger 3.触发器通用属性: JobK ...
- 基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...
- VUE2.0实现购物车和地址选配功能学习第七节
第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...
- delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行
第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行 以 Ado 为例,常见的方法是拖一个 AdoConnection 在窗口上(或 DataModule 中), 再配合 AdoQ ...
- centos Linux下磁盘管理 parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpfs ,nr_inodes, LVM,传统方式扩容文件系统 第七节课
centos Linux下磁盘管理 parted,df ,du,fdisk,partprobe,mkfs.ext4,mount,/etc/fstab,fsck,e2fsck,mk2efs,tmpf ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第七节
第七节:使用下一代CUDA硬件,快乐加速度 原文链接 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个 ...
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第七节:PS基础:UV动画
<使用Cocos2d-x 开发3D游戏>系列在线课程 第七节:PS基础:UV动画 视频地址:http://edu.csdn.net/course/attend/1330/20807 交流论 ...
- ES6 第七节 ES6中新增的数组知识(1)
目录 ES6 第七节 ES6中新增的数组知识(1) 第七节 ES6中新增的数组知识(1) JSON数组格式转换 Array.of()方法: find()实例方法: ES6 第七节 ES6中新增的数组知 ...
随机推荐
- 英语口语练习系列-C22-吃东西
基础词汇 1. bill [bɪl] n. 账单:钞票:法案:鸟嘴 Bill (人名)比尔 pay the bill 付账单 telephone bill 话费单 electricity bill 电 ...
- Django的认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- 线程池工厂方法newFixedThreadPool()和newCachedThreadPool()
newFixedThreadPool()方法: 该方法返回一个固定数量的线程池,当一个新的任务提交时,线程池中若有空闲线程,则立即执行. 若没有.则新的任务被暂存在一个任务队列中,待线程空闲时,便处理 ...
- jquery 选择器、筛选器、事件绑定与事件委派
一.jQuery简介 1.可用的jQuery服务器网站:https://www.bootcdn.cn/ jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTMLdocume ...
- springMVC使用HandlerMethodArgumentResolver 自定义解析器实现请求参数绑定方法参数
http://blog.csdn.net/truong/article/details/30971317 http://blog.csdn.net/fytain/article/details/439 ...
- TortoiseGit之配置密钥
TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址" -t rsa产生的密钥在Tortoi ...
- HBase原理分析
宏观架构 HBase从宏观上看只有HMaster.RegionServer和zookeeper三个组件. Master: 负责启动的时候分配Region到具体的RegionServer,执行各种管理操 ...
- go笔记-限速器(limiter)
参考: https://blog.csdn.net/wdy_yx/article/details/73849713https://www.jianshu.com/p/1ecb513f7632 http ...
- 如何展开Linux Memory Management学习?
Linux的进程和内存是两座大山,没有翻过这两座大山对于内核的理解始终是不完整的. 关于Linux内存管理,在开始之前做些准备工作. 首先bing到了Quora的<How can one rea ...
- 计算机网络基础知识-OSI七层协议模型
一.物理层 物理层主要规定了物理设备的标准,如网线的类型.光纤的接口类型.各种传输介质的传输速率,物理层的数据以比特流(二进制)的形式存在,传输时将比特流转化为电流强弱,达到目的地之后再转化为比特流. ...