【发布时间】:2019-01-05 05:02:23
【问题描述】:
我使用以下逻辑在单节点 Spring Batch 应用程序上重新启动未完成的作业:
public void restartUncompletedJobs() {
try {
jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
List<String> jobs = jobExplorer.getJobNames();
for (String job : jobs) {
Set<JobExecution> runningJobs = jobExplorer.findRunningJobExecutions(job);
for (JobExecution runningJob : runningJobs) {
runningJob.setStatus(BatchStatus.FAILED);
runningJob.setEndTime(new Date());
jobRepository.update(runningJob);
jobOperator.restart(runningJob.getId());
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
现在我正试图让它在两节点集群上工作。每个节点上的两个应用程序都将指向共享的 PostgreSQL 数据库。
让我们考虑以下示例:我有 2 个作业实例 - jobInstance1 现在正在 node1 上运行,jobInstance2 正在 node2 上运行。 Node1 在 jobInstance1 执行期间由于某种原因重新启动。在node1重新启动后,spring批处理应用程序尝试使用上面给出的逻辑重新启动未完成的作业-它看到有2个未完成的作业实例-jobInstance1和jobInstance2(在node2上正确运行)并尝试重新启动它们。这样可以重新启动唯一的jobInstance1 - 它将同时重新启动jobInstance1 和jobInstance2.. 但不应重新启动jobInstance2,因为它现在正在node2 上正确执行。
如何在应用启动过程中正确重启未完成的作业(前一次应用终止前),防止jobInstance2等作业也被重启的情况?
更新
这是以下答案中提供的解决方案:
Get the job instances of your job with JobOperator#getJobInstances
For each instance, check if there is a running execution using JobOperator#getExecutions.
2.1 If there is a running execution, move to next instance (in order to let the execution finish either successfully or with a failure)
2.2 If there is no currently running execution, check the status of the last execution and restart it if failed using JobOperator#restart.
我有一个关于 #2.1 的问题 - Spring Batch 会在应用程序重新启动后自动重新启动未完成的作业并运行执行,还是我需要执行手动操作才能这样做?
【问题讨论】:
标签: spring-boot spring-batch high-availability