目前,如果 Spring Batch 作业ExitStatus.ExitCode
失败,启动应用程序将以 0 退出代码结束。但是,我们收到了来自用户的多个请求,希望应用程序在ExitStatus.ExitCode
Spring Batch 作业返回 FAILED 时返回非零退出代码。
此功能应该是可配置的,默认行为应保持原样,但用户可以对其进行配置,以便启动应用程序在ExitStatus.ExitCode
失败时返回非零退出代码。
[spring-projects/spring-boot]作业失败的批处理应用程序应该能够返回非零退出代码
回答
@cppwfs 我想看看这个。通过快速浏览代码,我认为解决方案应该类似于org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator
,但使用可配置属性作为结果代码,而不是使用 的序数BatchStatus
,对吗?
@cppwfs:“getExitCode”在功能接口中定义为抽象方法ExitCodeGenerator
,更新getExitCode
类型将更改默认行为。我们可以在 /batch/JobExecutionExitCodeGenerator 中添加一个新方法,例如String getExitCodeStatus
带有自动配置返回代码的选项?我可以提交 PR。如果这看起来不错?
嗨@philwebb,你能指导我吗?如果没有其他人在做这件事,我想工作。谢谢。
@nishantraut 恐怕我不太熟悉 Spring Batch 的内部结构,所以我不太确定这里涉及什么。可能需要进行一些更改,JobExecutionExitCodeGenerator
但我不知道 Spring BatchExitStatus
是如何获得的。也许@mminella 有一些建议?
针对此问题提交的 PR:https://github.com/spring-projects/spring-boot/pull/15066
还请求@mminella @benas 进行评论
这可能是因为该应用程序是通过以下方式执行的:
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
而不是:
public static void main(String[] args) {
System.exit(
SpringApplication.exit(
SpringApplication.run(DemoApplication.class, args)
)
);
}
如批次样品中所述。如果像启动批处理示例一样运行,则失败的 Spring Batch 应用程序默认应返回 5(这是枚举中的序数)而不是 0。这是一个快速示例:FAILED
BatchStatus
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@EnableBatchProcessing
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.exit(
SpringApplication.exit(
SpringApplication.run(DemoApplication.class, args)
)
);
}
@Bean
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
Step step = stepBuilderFactory.get("step")
.tasklet((contribution, chunkContext) -> {
throw new Exception("Boom");
}).build();
return jobBuilderFactory.get("job")
.start(step)
.build();
}
}
但是,我们收到了多个用户请求,希望应用程序在 Spring Batch 作业的 ExitStatus.ExitCode 返回 FAILED 时返回非零退出代码。
我认为不需要在启动中添加新功能来实现这一点。 Boot 已经发出了JobExecutionEvent
,JobExecution
因此添加自定义ExitCodeGenerator
作为此类事件的侦听器就足够了,例如:
@Bean
public ExitCodeGenerator exitCodeGenerator () {
return new MyExitCodeGenerator();
}
class MyExitCodeGenerator implements ExitCodeGenerator, ApplicationListener<JobExecutionEvent> {
private JobExecution jobExecution;
@Override
public int getExitCode() {
ExitStatus exitStatus = jobExecution.getExitStatus();
if (ExitStatus.FAILED.getExitCode().equals(exitStatus.getExitCode())) {
return 42;
}
return 0;
}
@Override
public void onApplicationEvent(JobExecutionEvent jobExecutionEvent) {
this.jobExecution = jobExecutionEvent.getJobExecution();
}
}
将此 bean 添加到前面的示例中,使其在作业失败时返回 42。
谢谢@benas。查看您的样本和原始描述,并不清楚这里应该做什么。我将取消“理想贡献”,直到范围明确为止(至少对我来说)。
@benas 听起来不错。这是用户可以注册的东西,因此不需要新功能,在这种情况下,可以关闭此问题和 PR。
@snicoll 实际上没什么可做的,boot 已经提供了一种通过ExitCodeGenerator
.如果用户想要生成自定义退出代码,他/她必须注册一个自定义退出代码,ExitCodeGenerator
如上例所示。所以对我来说,ExitCodeGenerator
API就是这里所要求的功能。
对于这个问题迟来的插话深表歉意。我之所以推迟,是因为 Spring Cloud Task 中已经存在此功能,但已被破坏。我昨天合并了包含修复程序的 PR。您可以在这里看到我们的内容https://github.com/spring-cloud/spring-cloud-task/blob/master/spring-cloud-task-batch/src/main/java/org/springframework/cloud/task /batch/handler/TaskJobLauncherCommandLineRunner.java。这个问题最初是为了在此处捐赠该代码而打开的。
谢谢大家,那么我们就结束这个话题吧。
抱歉@mminella,我错过了那部分。您能否提交包含该代码的 PR,我非常乐意对其进行审核。
这
如果您在 SimpleJobLauncher 中配置了 SimplyAsyncTaskExecutor,则此操作不起作用。
@Override
protected JobLauncher createJobLauncher() throws Exception {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepository);
// To run 4 jobs parallelly.
SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
taskExecutor.setConcurrencyLimit(4);
simpleJobLauncher.setTaskExecutor(taskExecutor);
simpleJobLauncher.afterPropertiesSet();
return simpleJobLauncher;
}
关于如何实现从批处理作业返回非零状态代码的目标有什么想法吗?
@binbeast21 我们更喜欢仅使用 GitHub 问题来解决错误和增强功能,因此请在 Stack Overflow 或 Gitter 上提出此类问题。