gpt4 book ai didi

java - quartz 企业调度程序 : Job that schedules itself

转载 作者:行者123 更新时间:2023-11-29 08:16:00 25 4
gpt4 key购买 nike

我正在使用 Quartz Enterprise Job Scheduler (1.8.3)。作业配置来自几个 xml 文件,我们有一个特殊的作业可以检测这些 xml 文件中的更改并重新安排作业。这很有效,但问题是我还需要这个“调度程序作业”来重新安排自己。一旦这个工作重新安排了自己,出于某种原因,我看到它被执行了很多次。不过,我没有看到任何异常(exception)情况。

我已经复制并隔离了这个问题。这将是入口点:

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.rescheduleJobscheduler.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:20,018,作业如何正常运行。此时,作业重新安排自己每 50 秒运行一次。下次运行时(23:22:50,004),它会被调度数百次。

关于如何在 执行作业时配置作业有什么想法吗?我做错了什么?

谢谢!

最佳答案

简单。

首先,您对 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 秒内尽可能多次。

您需要将触发器的开始时间设置为 future (至少一秒),否则它会在您安排它的同一秒触发,如果时间表与当前秒相匹配的话。

此外,如果您真的需要每“N”秒类型的计划,我建议使用 SimpleTrigger 而不是 CronTrigger。 SimpleTrigger 可以执行“每 35 秒”或“每 50 秒”没问题。 CronTrigger 适用于“在 1 月每个星期一的 10 点钟的第 15 分钟和第 45 分钟的第 0、15、40 和 43 秒”这样的表达式。

关于java - quartz 企业调度程序 : Job that schedules itself,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4833713/

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