Trigger触发器

Quartz中,触发器用来指定在何种条件下执行Job。其中,最常用的就是通过时间计划来指定触发。当然,我们也可以自定义Trigger,不过这种场景比较罕见。

创建触发器

Quartz中我们通过TriggerBuilder创建触发器时,可以用withSchedule()方法指定一个计划任务调度规则。

Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("jobDetail", "demoGroup")
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
        .build();

上面例子中我们创建了一个每间隔1秒执行一次的计划任务触发器。SimpleScheduleBuilder中,有许多类似上面代码中的方法,可以组合成各种形式的计划任务。除此之外,基于Cron表达式创建触发器也很常用。

Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("jobDetail", "demoGroup")
        .withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
        .build();

CronScheduleBuilder中,我们能够组合基于Cron表达式的计划任务,这种方式更加简洁灵活,推荐使用。

Job超时阈值和misfire规则

“misfire”是指我们的Job错过了触发时机,有很多情况都可能造成Job错过触发时机,比如程序重启导致任务中断了一段时间,或是Quartz线程被其他任务占用很久导致一直无线程可用等情况。misfire是通过misfireThreshold参数来判定的,我们可以在quartz.properties配置中指定该超时阈值,它的默认值是60秒。

org.quartz.jobStore.misfireThreshold=60000

举例来说,假如我们的程序有一个10秒执行1次的定时任务,由于某些原因我们的程序意外停止了30秒,程序重新启动后,该任务Job已经错过了3次执行时机,但此时还未超过misfireThreshold,Quartz将立刻执行该任务3次;但如果我们的程序停止了1小时,它已经超过misfireThreshold了,我们的Job此时被认为发生了360次misfire。此时我们应该立即疯狂的执行360次任务,还是忽略它们继续按照原来的节奏执行?

Trigger的misfire规则机制定义了如何对这些错过的触发时机进行处理,所有类型的触发器都有一个自己默认的misfire规则,常用有如下3种处理策略:

Fire And Proceed:立即执行1次misfire,下一个周期正常执行

Do Nothing:不触发立即执行,正常执行下一个周期的任务

Ignore Misfires:所有的misfire立即执行,追上落后的调用次数

下面例子中,我们设置的misfire规则其表现就是Fire And Proceed,程序关闭一段时间超过了misfireThreshold后,错过的执行时会在程序恢复后立刻执行1次,然后继续按照1秒的周期执行。

Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("jobDetail", "demoGroup")
        .withSchedule(SimpleScheduleBuilder
                .simpleSchedule()
                .withIntervalInSeconds(1)
                .repeatForever()
                .withMisfireHandlingInstructionFireNow()
        )
        .build();
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap