我在使用Quartz时遇到了一个痛苦的问题并且失误了。
我的应用程序创建允许用户创建CronTrigger和SimpleTrigger作业。
每个作业都可以暂停/恢复(使用Scheduler.pauseJob和Scheduler.resumeJob)
调度程序本身可以设置为待机状态。
我们想放弃任何失误:
正如此博文http://www.nurkiewicz.com/2012/04/quartz-scheduler-misfire-instructions.html中所述,我已尝试
但没有人可以放弃失火。
我目前在作业执行方法中使用了一种丑陋的解决方法:
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.properties
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;
}
for 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;
}
答案 0 :(得分:3)
我不确定你是否想过这个问题,但是我遇到了类似的问题,我的解决方案与" misfireThreshold"相关。在我的配置中:
quartz.jobStore.misfireThreshold
我的设置为60000(也就是1分钟),所以在重新启动我的日程安排服务时,如果他们在一段时间内#34;迟到",他们仍然会执行。