我有一个配置了fixedDelay
或cron
的spring调度程序任务,并且该应用程序的多个实例在多个JVM上运行。
默认行为是所有实例都在执行调度程序任务。
有没有一种方法可以控制此行为,以便只有一个实例将执行调度程序任务,而其他实例则不执行。
[如果您知道任何方法,请告诉我。
谢谢
我们有类似的问题。我们像这样修复它:
@Scheduled
bean。这样,我们可以确保计划的任务在我们的服务集群中仅执行一次。
我曾遇到过类似的问题,即同一计划的批处理作业正在两台服务器上运行,而该服务器原本打算一次在一个节点上运行。但是后来我找到了一种解决方案,如果该作业已经在其他服务器上运行,则不执行该作业。
Job someJob = ...
Set<JobExecution> jobs = jobExplorer.findRunningJobExecutions("someJobName");
if (jobs == null || jobs.isEmpty()) {
jobLauncher.run(someJob, jobParametersBuilder.toJobParameters());
}
}
因此,在启动作业之前,需要检查该作业是否已在其他节点上执行。请注意,这种方法仅适用于基于数据库的作业存储库。
我们遇到了同样的问题,我们的三个实例每天执行相同的任务并执行三次任务。我们通过使用Spring批处理解决了这个问题。春季批处理只能具有唯一的作业ID,因此,如果您以日期等作业ID来启动作业,它将限制重复的作业以相同的ID开始。在我们的案例中,我们使用的日期类似于“ 2020-1-1”(因为它每天仅运行一次)。这三个实例均尝试启动ID为'2020-1-1'的作业,但spring拒绝了两个重复的作业,表明作业'2020-1-1'已在运行。