Java 正在多次运行作业的调度程序
我使用Quartz CronScheduler每15分钟执行一次作业。每次作业执行时,它都会检查数据库中cron表达式的任何更改,并为下次运行更新作业调度程序。我已通过以下方式实施了上述内容:Java 正在多次运行作业的调度程序,java,spring,quartz-scheduler,cronexpression,Java,Spring,Quartz Scheduler,Cronexpression,我使用Quartz CronScheduler每15分钟执行一次作业。每次作业执行时,它都会检查数据库中cron表达式的任何更改,并为下次运行更新作业调度程序。我已通过以下方式实施了上述内容: @Service public class QuartzSchedulerService { private static final Logger LOG = LoggerFactory.getLogger(QuartzSchedulerService.class); private
@Service
public class QuartzSchedulerService {
private static final Logger LOG = LoggerFactory.getLogger(QuartzSchedulerService.class);
private Scheduler scheduler;
@PostConstruct
private void init() {
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
} catch (Exception e) {
LOG.error("Unable to start quartz scheduler", e);
}
}
@PreDestroy
private void destroy() {
try {
scheduler.shutdown();
} catch (Exception e) {
LOG.error("Unable to shutdown quartz scheduler", e);
}
}
public void registerCronJob(Class<? extends Job> jobClass, String cronExpression) {
try {
String jobName = jobClass.getSimpleName();
CronScheduleBuilder cronBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName).build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName).withSchedule(cronBuilder).build();
scheduler.scheduleJob(jobDetail, cronTrigger);
LOG.info("Registered Cron Job:" + jobName + " " + jobDetail.getKey());
} catch (Exception e) {
LOG.error("Unable to register cron job", e);
}
}
public void updateCronSchedule(Class<? extends Job> jobClass, String cronExpression) {
try {
String jobName = jobClass.getSimpleName();
CronScheduleBuilder cronBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger newCronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName).withSchedule(cronBuilder).build();
scheduler.rescheduleJob(TriggerKey.triggerKey(jobName), newCronTrigger);
LOG.info("Updated Cron Job:" + jobName + " " + newCronTrigger.getJobKey());
LOG.info("Jobs executed: " + scheduler.getMetaData().getNumberOfJobsExecuted());
} catch (Exception e) {
LOG.error("Unable to reschedule cron job", e);
}
}
}
在上下文初始化期间调用loadAtStartup()方法,然后每15分钟调用一次execute()方法
使用的cron表达式是:0 0/15*1/1**代码>
现在,问题如下:
假设作业在3:00:00开始,它将在3:00:01之前执行尽可能多的次,而不是只执行一次
下一步作业将在3:15:00开始,并再次运行尽可能多的次数,直到3:15:01
作业每次执行的次数不同
我不确定是什么导致了这种行为。我已经用cronmaker测试了cron表达式
有人能指出这里的错误吗 既然cron表达式似乎正确,我想您的问题可能取决于您的工作逻辑,您是否尝试过其他工作?你为什么要在内部重新安排你的工作?@davioooh不,我没有..快速不-不能0 0/15*1/1**代码>简化为0 0/15****代码>-由于月日增量为1天?@AndersR.Bystrup是的,可以。。让我改变一下。我还启动了两个Tomcat,其中一个的代码与上面相同,而在另一个Tomcat中,重新加载不会更新cron计划,问题在第二个Tomcat中消失了。这可能意味着更新作业本身中的cron计划会导致某种问题。@sshntt我认为从作业内部重新计划作业可能会导致一些“递归灾难”:)因此我认为您需要创建一个单独的作业来进行检查,并在其中重新计划主作业
@Component
@DisallowConcurrentExecution
public class PropertiesReloadJob implements Job {
private static final Logger LOG = LoggerFactory.getLogger(PropertiesReloadJob.class);
@Autowired
private QuartzSchedulerService schedulerService;
@Autowired
private PropertiesService propertiesService;
public void loadAtStartup() {
load();
LOG.info("--- Registerting PropertiesReload Cron Job ---");
schedulerService.registerCronJob(PropertiesReloadJob.class, propertiesService.getCacheReloadCronExpression());
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
load();
LOG.info("--- Updating Pro Cron Job ---");
schedulerService.updateCronSchedule(PropertiesReloadJob.class, propertiesService.getCacheReloadCronExpression());
}
public void load(){
// Load properties from DB
}