具有多个实例和多个JVM的应用程序中的Spring Scheduler代码

问题描述 投票:1回答:3

我有一个配置了fixedDelaycron的spring调度程序任务,并且该应用程序的多个实例在多个JVM上运行。

默认行为是所有实例都在执行调度程序任务。

有没有一种方法可以控制此行为,以便只有一个实例将执行调度程序任务,而其他实例则不执行。

[如果您知道任何方法,请告诉我。

谢谢

spring spring-boot scheduled-tasks spring-batch
3个回答
2
投票

我们有类似的问题。我们像这样修复它:

  1. 从我们的Spring Boot服务中删除了所有@Scheduled bean。
  2. 已创建具有所需计划的AWS Lambda函数。
  3. Lambda函数通过调度请求进入我们的顶级域。
  4. 负载均衡器将此请求转发到服务实例之一。

这样,我们可以确保计划的任务在我们的服务集群中仅执行一次。


0
投票

我曾遇到过类似的问题,即同一计划的批处理作业正在两台服务器上运行,而该服务器原本打算一次在一个节点上运行。但是后来我找到了一种解决方案,如果该作业已经在其他服务器上运行,则不执行该作业。

Job someJob = ...
Set<JobExecution> jobs = jobExplorer.findRunningJobExecutions("someJobName");
if (jobs == null || jobs.isEmpty()) {
        jobLauncher.run(someJob, jobParametersBuilder.toJobParameters());
    }
}

因此,在启动作业之前,需要检查该作业是否已在其他节点上执行。请注意,这种方法仅适用于基于数据库的作业存储库。


0
投票

我们遇到了同样的问题,我们的三个实例每天执行相同的任务并执行三次任务。我们通过使用Spring批处理解决了这个问题。春季批处理只能具有唯一的作业ID,因此,如果您以日期等作业ID来启动作业,它将限制重复的作业以相同的ID开始。在我们的案例中,我们使用的日期类似于“ 2020-1-1”(因为它每天仅运行一次)。这三个实例均尝试启动ID为'2020-1-1'的作业,但spring拒绝了两个重复的作业,表明作业'2020-1-1'已在运行。

© www.soinside.com 2019 - 2024. All rights reserved.