Quartz框架(四)—misfire處理機制

Quartz框架(一)—Quartz的基本配置
Quartz框架(二)—jobstore數(shù)據(jù)庫表字段詳解
Quartz框架(三)—任務(wù)的并行/串行執(zhí)行
Quartz框架(四)—misfire處理機制
Quartz框架(五)— 有狀態(tài)的job和無狀態(tài)job
Quartz框架(六)— Trigger狀態(tài)轉(zhuǎn)換
Quartz框架(七)— Quartz集群原理
Quartz框架(八)— Quartz實現(xiàn)異步通知
Quartz框架(九)— 動態(tài)操作Quartz定時任務(wù)
Quartz框架(十)監(jiān)聽

什么叫做misfire

在Quartz中,當一個持久化的觸發(fā)器因為:
1. 調(diào)度器被關(guān)閉;
2. 線程池沒有可用線程;
3. 項目重啟佩憾;
4. 任務(wù)的串行執(zhí)行鸠信;
而錯過激活時間恼琼,就會發(fā)生激活失斶肽 (misfire)魂务。

此時我們需要明確兩個問題(1)如何判定激活失敿摇考阱;(2)如何處理激活失敗鞠苟;

1. 如何判定激活失敗

Quartz框架(一)—Quartz的基本配置中乞榨,quartz.properties配置文件中含有一個屬性是misfireThreshold(單位毫秒),用來指定調(diào)度引擎設(shè)置觸發(fā)器超時的“臨界值”当娱。也就是說Quartz對于任務(wù)的超時是有容忍度的吃既。只有超過這個容忍度才會判定位misfire。

quartz.properties的配置文件

#設(shè)置容忍度為12s
org.quartz.jobStore.misfireThreshold = 12000

Corn=[*/2 * * * * ?] 即每兩秒循環(huán)一次

jobDetail每次執(zhí)行需要7s

@Component
@DisallowConcurrentExecution
public class TestJob2 extends  CustomQuartzJobBean{
    private Logger logger = LoggerFactory.getLogger(TestJob2.class);

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        logger.info("【數(shù)據(jù)庫配置定時】-【開始】");
        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("【數(shù)據(jù)庫配置定時】-【結(jié)束】");
    }
}
任務(wù)編號 預(yù)定運行時刻 實際運行時刻 延遲量(秒)
1 17:54:00 17:54:00 0
2 17:54:02 17:54:07 5
3 17:54:04 17:54:14 10
4 17:54:06 17:54:21 misfire

從表中可以看到跨细,每一次任務(wù)的延遲都是5s作用鹦倚,該延遲量不斷累積,并且與misfireThreshold比較冀惭,直到在17:54:21時發(fā)生了misfire震叙,那么17:54:21第4次任務(wù)會不會執(zhí)行呢掀鹅,答案是不一定的,取決于配置媒楼。

2. 激活失敗的處理

激活失敗指令(Misfire Instruction[因死抓可神 指令])是觸發(fā)器的一個重要配置乐尊。所有類型的觸發(fā)器都有一個默認的指令:

Trigger.MISFIRE_INSTRUCTION_SMART_POLICY

但是這個“機智策略(policy [跑了誰] )”對于不同類型的觸發(fā)器其具體行為是不同的。

misfire Instruction在qutz_triggers表中的字段划址。

misfire Instruction.png

代碼中設(shè)置misfire策略的方式扔嵌。

2.1 quartz中CornTrigger使用的策略

//所有的misfile任務(wù)馬上執(zhí)行
public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;
//在Trigger中默認選擇MISFIRE_INSTRUCTION_FIRE_ONCE_NOW 策略
public static final int MISFIRE_INSTRUCTION_SMART_POLICY = 0;
// CornTrigger默認策略,合并部分misfire夺颤,正常執(zhí)行下一個周期的任務(wù)痢缎。
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
//所有的misFire都不管,執(zhí)行下一個周期的任務(wù)拂共。
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
  • 可以通過setMisfireInstruction方法設(shè)置misfire策略牺弄。
 CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean();
 triggerFactoryBean.setName("corn_" + clazzName);
 triggerFactoryBean.setJobDetail(jobFactory.getObject());
 triggerFactoryBean.setCronExpression(quartzCorn);
 triggerFactoryBean.setGroup(QUARTZ_TRIGGER_GROUP);
 //設(shè)置misfire策略
 triggerFactoryBean.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY);
 triggerFactoryBean.afterPropertiesSet();
  • 也可以通過CronScheduleBuilder設(shè)置misfire策略姻几。
 CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
 //MISFIRE_INSTRUCTION_DO_NOTHING
 csb.withMisfireHandlingInstructionDoNothing();
 //MISFIRE_INSTRUCTION_FIRE_ONCE_NOW
 csb.withMisfireHandlingInstructionFireAndProceed();//(默認)
 //MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
 csb.withMisfireHandlingInstructionIgnoreMisfires();

策略的具體含義

前提:在每個星期周一下午5點到7點宜狐,每隔一個小時執(zhí)行一次,理論上共執(zhí)行3次蛇捌。

1. 情景一:

//所有misfire的任務(wù)會馬上執(zhí)行
public static final int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;

若是5點misfire抚恒,6:15系統(tǒng)恢復(fù)之后,5,6點的misfire會馬上執(zhí)行络拌。

2. 情景二:

//不做任何事情
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;

若是5點misfire俭驮,6:15系統(tǒng)恢復(fù)之后,只會執(zhí)行7點的misfire春贸。如果下次執(zhí)行時間超過了end time混萝,實際上就沒有執(zhí)行機會了。

3. 情景三:(cronTrigger的默認策略)

// CornTrigger默認策略萍恕,合并部分misfire逸嘀,正常執(zhí)行下一個周期的任務(wù)。
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;

若是5點misfire允粤,6:15系統(tǒng)恢復(fù)之后崭倘,立刻執(zhí)行一次(只會一次)misfire。

2.2 quartz中SImpleTrigger使用的策略

  1. 若是使用MISFIRE_INSTRUCTION_SMART_POLICY—機智的策略

    • 如果Repeat=0; 【重復(fù)0次】
      instruction selected = MISFIRE_INSTRUCTION_FIRE_NOW;【立刻執(zhí)行类垫,對于不會重復(fù)執(zhí)行的任務(wù)司光,只是默認的處理策略∠せ迹】
    • 如果Repeat Count=REPEAT_INDEFINITELY;【無限重復(fù)】
      instruction selected = MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT;【在下一個激活點執(zhí)行残家,且錯過的執(zhí)行機會作廢∈墼辏】
    • 如果Repeat Count>0;【有限重復(fù)】
      instruction selected = MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT;【立即執(zhí)行坞淮,并執(zhí)行指定的次數(shù)谴仙。】

3. misfire的執(zhí)行流程

  1. 若配置(默認為true碾盐,可配置)成獲取鎖前先檢查是否有需要recovery的trigger晃跺,先獲取misfireCount;
  2. 獲取TRIGGER_ACCESS鎖毫玖;
  3. misfired的判斷依據(jù):status=waiting掀虎,current_time-next_fire_time>misfireThreshold(可配置,默認1分鐘)【即實際觸發(fā)時間-預(yù)計觸發(fā)時間大于容忍度時間】付枫,獲取misfired的trigger烹玉,默認一個事務(wù)中只能最大有20個misfired trigger(可配置)。
  4. updateAfterMisfired:獲取misfired的策略(默認是MISFIRE_INSTRUCTION_SMART_POLICY該策略在CronTrigger中為MISFIRE_INSTRUCTION_FIRE_ONCE_NOW)阐滩,根據(jù)策略更新nexFireTime二打。
  5. 將nextFireTime等更新到trigger表;
  6. commit connection掂榔,釋放鎖继效。
misfired執(zhí)行流程

文章參考

Quartz的misfire處理機制分析

任務(wù)框架quartz的misfire理解

Quartz原理解密

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市装获,隨后出現(xiàn)的幾起案子瑞信,更是在濱河造成了極大的恐慌,老刑警劉巖穴豫,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凡简,死亡現(xiàn)場離奇詭異,居然都是意外死亡精肃,警方通過查閱死者的電腦和手機秤涩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來司抱,“玉大人筐眷,你說我怎么就攤上這事∽粗玻” “怎么了浊竟?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長津畸。 經(jīng)常有香客問我振定,道長,這世上最難降的妖魔是什么肉拓? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任后频,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卑惜。我一直安慰自己膏执,他們只是感情好,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布露久。 她就那樣靜靜地躺著更米,像睡著了一般。 火紅的嫁衣襯著肌膚如雪毫痕。 梳的紋絲不亂的頭發(fā)上征峦,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音消请,去河邊找鬼栏笆。 笑死,一個胖子當著我的面吹牛臊泰,可吹牛的內(nèi)容都是我干的蛉加。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼缸逃,長吁一口氣:“原來是場噩夢啊……” “哼针饥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起察滑,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤打厘,失蹤者是張志新(化名)和其女友劉穎修肠,沒想到半個月后贺辰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡嵌施,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年饲化,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吗伤。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡吃靠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出足淆,到底是詐尸還是另有隱情巢块,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布巧号,位于F島的核電站族奢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丹鸿。R本人自食惡果不足惜越走,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧廊敌,春花似錦铜跑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肋殴,卻和暖如春伞广,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疼电。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工嚼锄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔽豺。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓区丑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親修陡。 傳聞我的和親對象是個殘疾皇子沧侥,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344