Quartz CronScheduler多次运行作业

时间:2015-05-19 12:55:36

标签: java spring quartz-scheduler cronexpression

我使用Quartz CronScheduler每15分钟执行一次作业。每次执行作业时,都会检查DB以查找cron表达式中的任何更改,并更新作业调度程序以进行下一次运行。我已通过以下方式实现了上述内容:

@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);
        }
    }

}

实现Job接口的类如下:

@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
    }

在上下文初始化期间调用loadAtStartup()方法,然后在每15分钟调用一次execute()方法。

使用的cron表达式为:0 0/15 * 1/1 * ? *

现在,问题如下: 假设作业从3:00:00开始,它将执行多次,直到3:00:01,而不是仅执行一次。

接下来,作业将在3:15:00开始,并且可以再次运行至3:15:01。

每次作业执行的次数都不同。

我不确定导致此行为的原因。我用cronmaker测试了cron表达式。

有人可以在这里指出错误吗?

0 个答案:

没有答案