在我们的后台库中,我们通过工厂方法创建触发器
public Trigger buildTrigger(final JobDescription jobDescription) {
final JobDescription.TriggerType triggerType = jobDescription.getTriggerType();
if (triggerType == null) {
throw new IllegalArgumentException("trigger type can not be empty");
}
return switch (triggerType) {
case CRON -> makeCronTrigger(jobDescription);
case ONCE -> makeOnceTrigger(jobDescription);
case MULTIPLE_TIMES -> makeMultipleTimesTrigger(jobDescription);
case LOOP -> makeLoopTrigger(jobDescription);
};
}
private CronScheduleBuilder createCronSchedule(JobDescription jobDescription) {
CronScheduleBuilder cronSchedule = null;
MisfirePolicy misfirePolicy = jobDescription.getMisfirePolicy() != null ? jobDescription.getMisfirePolicy() : MisfirePolicy.None;
switch (misfirePolicy) {
case DoNothing:
cronSchedule = cronSchedule(jobDescription.getCronExpression()).withMisfireHandlingInstructionDoNothing();
break;
case FireAndProceed:
cronSchedule = cronSchedule(jobDescription.getCronExpression()).withMisfireHandlingInstructionFireAndProceed();
break;
case IgnoreMisfires:
cronSchedule = cronSchedule(jobDescription.getCronExpression()).withMisfireHandlingInstructionIgnoreMisfires();
break;
default:
cronSchedule = cronSchedule(jobDescription.getCronExpression());
}
return cronSchedule;
}
private Trigger makeCronTrigger(final JobDescription jobDescription) {
final TriggerBuilder<CronTrigger> cronTriggerTriggerBuilder = newTrigger()
.withIdentity(jobDescription.getJobId())
.withSchedule(createCronSchedule(jobDescription))
.withPriority(getPriorityValue(jobDescription));
setIdentity(jobDescription, cronTriggerTriggerBuilder);
return cronTriggerTriggerBuilder.build();
}
在我们的功能性微服务中,我们构建了将利用触发器的作业
@Bean
@ConditionalOnProperty(prefix = "tickets.background.job", name = "deliver-tickets.enabled", havingValue = "true")
JobDescription deliverTicketsJobDescription() {
final long now = metrics ? System.currentTimeMillis() : 0;
JobDescription jobDescription = JobDescriptionBuilder.builder()
.triggerType(TriggerType.CRON)
.jobClass(DeliverTicketsJob.class)
.cronExpression(deliverTicketsCron) // 0/5 * * * * ?
.misfirePolicy(MisfirePolicy.FireAndProceed)
.jobGroupId(jobGroupId)
.jobId("deliverTickets")
.build();
if (metrics) {
LOGGER.debug("METRIC: deliverTicketsJobDescription ~ duration: " + (System.currentTimeMillis() - now) + "ms");
}
return jobDescription;
}
我们还将misfireThreshold 设置为1 秒
public class TicketApplication {
static {
System.setProperty("quartz.jobStore.misfireThreshold", "1000");
}
我已经通过查看 qrtz_triggers 表并查看我们的工作和 Misfire_instruction 列集进行了验证。
但是从我的角度来看,处理失火的行为永远不会改变,它始终是:
对我来说,这些步骤说明了失火的处理方法。从启动时(从关闭时)以及作业花费的时间长于间隔时开始失火。失败作业的执行应该通过分配的
MisfireHandlingInstruction
来控制,但就像我说的,它对上面列出的步骤的结果没有影响,我尝试了所有这些。