gpt4 book ai didi

java - 使用 Quartz 避免失火

转载 作者:搜寻专家 更新时间:2023-10-31 20:18:26 26 4
gpt4 key购买 nike

我正面临 Quartz 和失火的痛苦问题。

我的应用创建允许用户创建 CronTrigger 和 SimpleTrigger 作业。

每个作业都可以暂停/恢复(使用 Scheduler.pauseJob 和 Scheduler.resumeJob)

调度器本身可以设置为备用。

我们想丢弃任何失火:

  • 当调度器处于待机状态时
  • 作业暂停时
  • 应用程序停止时

正如这篇博客文章中所解释的那样 http://www.nurkiewicz.com/2012/04/quartz-scheduler-misfire-instructions.html , 我试过了

  • CronTrigger 的 withMisfireHandlingInstructionDoNothing 策略
  • 用于 SimpleTrigger 的 withMisfireHandlingInstructionNextWithRemainingCount

但没有人可以丢弃哑火。

我目前在作业执行方法中使用了一个丑陋的解决方法:

public void execute(JobExecutionContext context) throws JobExecutionException {
Date dateNow = new Date();
long diff = dateNow.getTime() - context.getScheduledFireTime().getTime();
if (diff > 500)
{
//its a misfire
return;
}

/* rest of job execution code */

当 scheduledFireTime 比现在早 500 毫秒以上时,丢弃它。

但似乎有时,在生产中,这允许执行一些作业(据报道在应用程序重新启动时发生)

这可能吗?有什么好的方法可以避免失火吗?

Quartz 版本:2.1.7(在 Spring 3.2.5 应用程序中)

quartz .属性

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource=psqldatasource
org.quartz.dataSource.psqldatasource.driver=${db.driver}
org.quartz.dataSource.psqldatasource.URL=${db.url}
org.quartz.dataSource.psqldatasource.user=${db.usr}
org.quartz.dataSource.psqldatasource.password=${db.pwd}
org.quartz.threadPool.threadCount = 3

org.quartz.jobStore.useProperties = false
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

对于 Cron:

 JobDetail job = JobBuilder.newJob(JobLauncher.class)
.withIdentity(jobIdentifierBean.getNameJob(), jobIdentifierBean.getNameGroup())
.usingJobData(...) //defining some jobData key/values
.build();

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(name, group)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(strCronExpression).withMisfireHandlingInstructionDoNothing())
.build();

try {
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
throw e;
}

对于 SimpleTrigger(作业定义为 cron 情况)

    //avoid first fire
GregorianCalendar g = new GregorianCalendar();
switch (enumDelayUnits) {
case Days:
g.add(GregorianCalendar.HOUR, delay * 24);
break;
case Hours:
g.add(GregorianCalendar.HOUR, delay);
break;
case Minutes:
g.add(GregorianCalendar.MINUTE, delay);
break;
case Seconds:
g.add(GregorianCalendar.SECOND, delay);
break;
default:
throw new ServiceException("Unknow delay type");
}

Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobIdentifierBean.getNameTrigger(), jobIdentifierBean.getNameGroup())
.startAt(g.getTime())
.withSchedule(getSimpleScheduleBuilder(delay, enumDelayUnits, repeatForever))
.build();
try {
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
throw e;
}

private SimpleScheduleBuilder getSimpleScheduleBuilder(int delay, EnumDelayUnits enumDelayType, boolean repeatForever) throws ServiceException, Exception
{
SimpleScheduleBuilder simpleScheduleBuilder;

simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
switch (enumDelayType) {
case Days:
simpleScheduleBuilder.withIntervalInHours(24 * delay);
break;
case Hours:
simpleScheduleBuilder.withIntervalInHours(delay);
break;
case Minutes:
simpleScheduleBuilder.withIntervalInMinutes(delay);
break;
case Seconds:
simpleScheduleBuilder.withIntervalInSeconds(delay);
break;
default:
serviceError("Unknown delay " + enumDelayType);
}
if(repeatForever)
{
simpleScheduleBuilder.repeatForever();
}

simpleScheduleBuilder = simpleScheduleBuilder.withMisfireHandlingInstructionNextWithRemainingCount();

return simpleScheduleBuilder;
}

最佳答案

我不确定你是否想过这个问题,但我遇到了类似的问题,我的解决方案与我配置中的“misfireThreshold”有关:

quartz.jobStore.misfireThreshold

我的设置为 60000(又名 1 分钟),因此在重新启动我的调度服务时,如果它们在“迟到”的一分钟内,它们仍然会执行。

关于java - 使用 Quartz 避免失火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32075128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com