1.问题描述
在使用Quartz.net定时运行作业时,存在一种情况:作业错过了某次执行,当作业恢复的时候应该怎么处理?如:job1在3:50的时候应该执行的,但此刻job1处于暂停状态,而到3:55的时候,job1 resume,那么错过的3:50该怎么处理?
对此,Quartz.net使用misfire机制,misfire可以翻译为"错过了触发"。
2.misfire机制
这里以CronTrigger为例,提供了两种可选的值,
DoNothing:不触发立即执行。等待下次Cron触发频率到达时刻开始按照Cron频率依次执行。即如果错过了某次执行,直接忽略。
FireOnceNow:以当前时间为触发频率立刻触发一次执行,然后按照Cron频率依次执行。
而原始的Quartz的还提供了更多的选项:
1 <xs:simpleType name="simple-trigger-misfire-instructionType"> 2 <xs:annotation> 3 <xs:documentation>Simple Trigger Misfire Instructions</xs:documentation> 4 </xs:annotation> 5 <xs:restriction base="xs:string"> 6 <xs:pattern value="SmartPolicy" /> 7 <xs:pattern value="RescheduleNextWithExistingCount" /> 8 <xs:pattern value="RescheduleNextWithRemainingCount" /> 9 <xs:pattern value="RescheduleNowWithExistingRepeatCount" /> 10 <xs:pattern value="RescheduleNowWithRemainingRepeatCount" /> 11 <xs:pattern value="FireNow" /> 12 <xs:pattern value="IgnoreMisfirePolicy" /> 13 </xs:restriction> 14 </xs:simpleType> 15 16 <xs:simpleType name="cron-trigger-misfire-instructionType"> 17 <xs:annotation> 18 <xs:documentation>Cron Trigger Misfire Instructions</xs:documentation> 19 </xs:annotation> 20 <xs:restriction base="xs:string"> 21 <xs:pattern value="SmartPolicy" /> 22 <xs:pattern value="DoNothing" /> 23 <xs:pattern value="FireOnceNow" /> 24 <xs:pattern value="IgnoreMisfirePolicy" /> 25 </xs:restriction> 26 </xs:simpleType> 27 28 <xs:simpleType name="date-interval-trigger-misfire-instructionType"> 29 <xs:annotation> 30 <xs:documentation>Date Interval Trigger Misfire Instructions</xs:documentation> 31 </xs:annotation> 32 <xs:restriction base="xs:string"> 33 <xs:pattern value="SmartPolicy" /> 34 <xs:pattern value="DoNothing" /> 35 <xs:pattern value="FireOnceNow" /> 36 <xs:pattern value="IgnoreMisfirePolicy" /> 37 </xs:restriction> 38 </xs:simpleType>
3.如何使用?
3.1 配置文件中
1 <!--清除日志文件--> 2 <job> 3 <name>RemoveLogFileEveryDay</name> 4 <group>InnerBusiness</group> 5 <description>每天清除两周以前的日志文件</description> 6 <job-type>NS.RemoveLogFileEveryDay, NS</job-type> 7 <durable>false</durable> 8 <recover>true</recover> 9 </job> 10 <trigger> 11 <cron> 12 <name>RemoveLogFileEveryDayTrigger</name> 13 <group>RemoveLogFileEveryDayTrigger</group> 14 <description>每天23:00点执行一次</description> 15 <job-name>RemoveLogFileEveryDay</job-name> 16 <job-group>InnerBusiness</job-group> 17 <misfire-instruction>DoNothing</misfire-instruction> 18 <cron-expression>0 0 23 * * </cron-expression> 19 </cron> 20 </trigger>
如上:配置了DoNothing。
3.2 代码中
ICronTrigger myCronTrigger = scheduler.GetTrigger(triggerKey) as ICronTrigger; myCronTrigger.GetTriggerBuilder().WithCronSchedule(cronExpresion, (zw) => { zw.WithMisfireHandlingInstructionDoNothing(); }).Build();
仍然配置了DoNothing
4.艰辛的过程:查找配置方法——?<misfire-instruction>DoNothing</misfire-instruction>
一开始,我就想搜一下,如何配置misfire-instruction的配置,但是怎么都找不到,网上有一堆关于quartz_jobs.xml的配置的例子,可是都没有misfire的配置,因为misfire模式使用的FireOnceNow。
于是去官网的API搜索配置,还是没有找到
然后看到了github,就下载了代码
找到这个文件XMLSchedulingDataProcessor.cs,继续找到QuartzXmlConfiguration20,
XmlSerializer xs = new XmlSerializer(typeof (QuartzXmlConfiguration20));
终于知道是misfire-instruction,而且必须配置在cron-expression的前面,比较严格
继续找到枚举值,直接配置字符串而已~