第七节:Trigger(SimpleTrigger、CronTrigger)哑火(MisFire)策略 :
一. 簡介
1. 什么是啞火
由于某些原因導致觸發器(trigger)在該觸發的時候沒有得到觸發,后續對應的解決策略即為啞火策略。(個人理解)
2. 啞火觸發的條件
?、?#xff1a;所有的工作線程都在忙碌,導致某些trigger得不到觸發.(如:simplethreadpool 默認是10個工作線程,但我有15個trigger同時觸發,?恰巧這10個trigger關聯的job耗時都很長,剩下的5個trigger超過了等待時間仍然沒有得到觸發)
②:調度器(sheduler)中途掛了,某個時間又恢復了
?、?#xff1a;設置的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: 立即執行,執行的開始時間改為當前時間,執行次數永久執行
代碼分享:自行替換即可
1 public static void misfireShow()2 {3 //1.創建Schedule4 IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();5 //2.創建job (具體的job需要單獨在一個文件中執行)6 var job = JobBuilder.Create<HelloJob4>().Build();7 //3.配置trigger 8 //下面的四個觸發器對應了上面四種情況的測試,時間需要根據實際情況進行配置測試來設置9 var trigger1 = TriggerBuilder.Create().StartAt(DateBuilder.DateOf(20, 0, 0)) 10 .WithSimpleSchedule(x => x.WithIntervalInMinutes(30) 11 .WithRepeatCount(8) 12 .WithMisfireHandlingInstructionNowWithExistingCount() 13 ).Build(); 14 var trigger2 = TriggerBuilder.Create().StartAt(DateBuilder.DateOf(18, 0, 0)) 15 .WithSimpleSchedule(x => x.WithIntervalInSeconds(1) 16 .WithRepeatCount(1) 17 .WithMisfireHandlingInstructionFireNow() 18 ).Build(); 19 var trigger3 = TriggerBuilder.Create() 20 .StartAt(DateBuilder.DateOf(15, 0, 0, 5, 3, 2018)) 21 .WithSimpleSchedule(x => x.WithIntervalInMinutes(1) 22 .WithMisfireHandlingInstructionNowWithRemainingCount() 23 .RepeatForever()).Build(); 24 var trigger4 = TriggerBuilder.Create() 25 .StartAt(DateBuilder.DateOf(14, 0, 0)) 26 .WithCronSchedule("0 0-59 9-23 ? * MON-FRI",x=>x.WithMisfireHandlingInstructionIgnoreMisfires()).Build(); 27 28 //4.開始調度 29 scheduler.ScheduleJob(job, trigger1); 30 scheduler.Start(); 31 }?
三. CronTrigger啞火策略詳解
(1). 默認:錯過的合并,于當前時間執行一次,不修改調度時間,按計劃等待下一次調度(等價于下面的 WithMisfireHandlingInstructionFireAndProceed)
(2). WithMisfireHandlingInstructionIgnoreMisfires:錯過的立即追趕,然后正常調度
ps:錯過多少次,初次執行的時候追趕多少次,追趕的次數的時間是按原規律執行的時間,然后按照原規律進行正常后續調度
(3). WithMisfireHandlingInstructionFireAndProceed:錯過的合并,于當前時間執行一次,不修改調度時間,按計劃等待下一次調度
PS:無論錯過多少次,均在初次運行的時候,即當前時間執行一次,后續的執行仍按照原規律進行執行。
(4). WithMisfireHandlingInstructionDoNothing:錯過的不管了,后續按照正常調度進行
PS:無論錯過多少次,均忽略,后續的執行仍按照原規律進行執行。
?代碼詳見上面的代碼分享
?
總結
以上是生活随笔為你收集整理的第七节:Trigger(SimpleTrigger、CronTrigger)哑火(MisFire)策略 :的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本周国债将迎来密集发行期,还有一批特别国
- 下一篇: 我国人均GDP已超7万元,却还有6亿人月