Java Quartz Enterprise Scheduler:自行调度的作业
我使用的是Quartz Enterprise作业调度器1.8.3。作业配置来自多个xml文件,我们有一个特殊的作业,用于检测这些xml文件中的更改并重新安排作业。这很有效,但问题是我还需要这个调度程序作业来重新调度自己。由于某种原因,一旦这个作业重新安排了自己的时间,我就会看到它被执行了很多次。不过,我没有看到任何例外 我已经复制并隔离了这个问题。这将是一个切入点:Java Quartz Enterprise Scheduler:自行调度的作业,java,quartz-scheduler,job-scheduling,Java,Quartz Scheduler,Job Scheduling,我使用的是Quartz Enterprise作业调度器1.8.3。作业配置来自多个xml文件,我们有一个特殊的作业,用于检测这些xml文件中的更改并重新安排作业。这很有效,但问题是我还需要这个调度程序作业来重新调度自己。由于某种原因,一旦这个作业重新安排了自己的时间,我就会看到它被执行了很多次。不过,我没有看到任何例外 我已经复制并隔离了这个问题。这将是一个切入点: public class App { public static void main(final String[] arg
public class App {
public static void main(final String[] args) throws ParseException, SchedulerException {
// get the scheduler from the factory
final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// start the scheduler
scheduler.start();
// schedule the job to run every 20 seconds
final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class);
final Trigger trigger = new CronTrigger("triggername", "groupname", "*/20 * * * * ?");
// set the scheduler in the job data map, so the job can re-configure itself
jobDetail.getJobDataMap().put("scheduler", scheduler);
// schedule job
scheduler.scheduleJob(jobDetail, trigger);
}
}
这将是工作类:
public class TestJob implements Job {
private final static Logger LOG = Logger.getLogger(TestJob.class);
private final static AtomicInteger jobExecutionCount = new AtomicInteger(0);
public void execute(final JobExecutionContext context) throws JobExecutionException {
// get the scheduler from the data map
final Scheduler scheduler = (Scheduler) context.getJobDetail().getJobDataMap().get("scheduler");
LOG.info("running job! " + jobExecutionCount.incrementAndGet());
// buid the job detail and trigger
final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class);
// this time, schedule it to run every 35 secs
final Trigger trigger;
try {
trigger = new CronTrigger("triggername", "groupname", "*/50 * * * * ?");
} catch (final ParseException e) {
throw new JobExecutionException(e);
}
trigger.setJobName("jobname");
trigger.setJobGroup("groupname");
// set the scheduler in the job data map, so this job can re-configure itself
jobDetail.getJobDataMap().put("scheduler", scheduler);
try {
scheduler.rescheduleJob(trigger.getName(), jobDetail.getGroup(), trigger);
} catch (final SchedulerException e) {
throw new JobExecutionException(e);
}
}
}
我尝试了scheduler.rescheduleJob和scheduler.deleteJob,然后是scheduler.scheduleJob。无论我做什么,这都是我使用log4j得到的输出:
23:22:15,874 INFO SchedulerSignalerImpl:60 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
23:22:15,878 INFO QuartzScheduler:219 - Quartz Scheduler v.1.8.3 created.
23:22:15,883 INFO RAMJobStore:139 - RAMJobStore initialized.
23:22:15,885 INFO QuartzScheduler:241 - Scheduler meta-data: Quartz Scheduler (v1.8.3)
'MyScheduler' with instanceId '1'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
23:22:15,885 INFO StdSchedulerFactory:1275 - Quartz scheduler 'MyScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
23:22:15,886 INFO StdSchedulerFactory:1279 - Quartz scheduler version: 1.8.3
23:22:15,886 INFO QuartzScheduler:497 - Scheduler MyScheduler_$_1 started.
23:22:20,018 INFO TestJob:26 - running job! 1
23:22:50,004 INFO TestJob:26 - running job! 2
23:22:50,010 INFO TestJob:26 - running job! 3
23:22:50,014 INFO TestJob:26 - running job! 4
23:22:50,016 INFO TestJob:26 - running job! 5
...
23:22:50,999 INFO TestJob:26 - running job! 672
23:22:51,000 INFO TestJob:26 - running job! 673
请注意,在23:22:20018,作业运行正常。此时,作业会重新安排自己每50秒运行一次。下次在23:22:50004运行时,它会被安排数百次
关于如何在执行作业时配置作业,有什么想法吗?我做错了什么
谢谢 简单
首先,您对Cron表达式有一些误解*/20 * * * * ? 正如注释所暗示的,是每二十秒一次,但这仅仅是因为60可以被20整除/50 ... 不是每五十秒一次。它是每分钟的0秒和50秒。作为另一个例子,/13。。。是每分钟的0秒、13秒、26秒、39秒和52秒,所以在第52秒和下一分钟的0秒之间,只有8秒,而不是13秒。因此,使用*/50时,每隔一次发射间隔为50秒,其他发射间隔为10秒
然而,这并不是你迅速解雇这份工作的原因。问题是,当前秒数是50,而您正在计划新触发器在秒数为50时触发,因此它会立即触发。然后仍然是第二个50秒,作业再次执行,它安排另一个触发器在第二个50秒触发,以此类推,在第50秒期间尽可能多次触发
您需要将触发器的开始时间设置为未来至少1秒,否则如果计划与当前秒相匹配,它将在您计划触发器的同一秒触发
另外,如果您确实需要每N秒一次的计划,我建议使用SimpleTrigger而不是CronTrigger。SimpleTrigger可以每35秒或每50秒执行一次没有问题。CronTrigger的意思是在1月的每个星期一的10点15分和45分的第0秒、第15秒、第40秒和第43秒
首先,您对Cron表达式有一些误解*/20 * * * * ? 正如注释所暗示的,是每二十秒一次,但这仅仅是因为60可以被20整除/50 ... 不是每五十秒一次。它是每分钟的0秒和50秒。作为另一个例子,/13。。。是每分钟的0秒、13秒、26秒、39秒和52秒,所以在第52秒和下一分钟的0秒之间,只有8秒,而不是13秒。因此,使用*/50时,每隔一次发射间隔为50秒,其他发射间隔为10秒
然而,这并不是你迅速解雇这份工作的原因。问题是,当前秒数是50,而您正在计划新触发器在秒数为50时触发,因此它会立即触发。然后仍然是第二个50秒,作业再次执行,它安排另一个触发器在第二个50秒触发,以此类推,在第50秒期间尽可能多次触发
您需要将触发器的开始时间设置为未来至少1秒,否则如果计划与当前秒相匹配,它将在您计划触发器的同一秒触发
另外,如果您确实需要每N秒一次的计划,我建议使用SimpleTrigger而不是CronTrigger。SimpleTrigger可以每35秒或每50秒执行一次没有问题。CronTrigger用于表达式,如1月每个星期一10点15分和45分的0秒、15秒、40秒和43秒。很有意义,我更改了测试应用程序的代码,现在它的行为符合我的预期。。。多亏了这一点,我改变了测试应用程序的代码,现在它的行为符合我的预期。。。谢谢