配置Step
以支持重启
在“配置和运行作业”部分中,讨论了重启Job
。重启对步骤有许多影响,因此可能需要一些特定的配置。
设置启动限制
在许多情况下,您可能希望控制可以启动Step
的次数。例如,您可能需要配置特定的Step
,使其仅运行一次,因为它会使某些资源无效,必须手动修复这些资源才能再次运行。这可以在步骤级别进行配置,因为不同的步骤可能有不同的需求。只能执行一次的Step
可以作为同一Job
中可以无限次运行的Step
的一部分存在。
-
Java
-
XML
以下代码片段显示了在 Java 中配置启动限制的示例
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.startLimit(1)
.build();
}
以下代码片段显示了在 XML 中配置启动限制的示例
<step id="step1">
<tasklet start-limit="1">
<chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
</tasklet>
</step>
前面示例中显示的步骤只能运行一次。尝试再次运行它会导致抛出StartLimitExceededException
异常。请注意,启动限制的默认值为Integer.MAX_VALUE
。
重启已完成的Step
对于可重启作业,可能存在一个或多个步骤应始终运行,无论它们第一次是否成功。一个例子可能是一个验证步骤或一个在处理前清理资源的Step
。在重启作业的正常处理过程中,任何状态为COMPLETED
(表示已成功完成)的步骤都会被跳过。将allow-start-if-complete
设置为true
会覆盖此设置,以便该步骤始终运行。
-
Java
-
XML
以下代码片段显示了如何在 Java 中定义可重启作业
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.allowStartIfComplete(true)
.build();
}
以下代码片段显示了如何在 XML 中定义可重启作业
<step id="step1">
<tasklet allow-start-if-complete="true">
<chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
</tasklet>
</step>
Step
重启配置示例
-
Java
-
XML
以下 Java 示例显示了如何配置作业以具有可重启的步骤
@Bean
public Job footballJob(JobRepository jobRepository, Step playerLoad, Step gameLoad, Step playerSummarization) {
return new JobBuilder("footballJob", jobRepository)
.start(playerLoad)
.next(gameLoad)
.next(playerSummarization)
.build();
}
@Bean
public Step playerLoad(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("playerLoad", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(playerFileItemReader())
.writer(playerWriter())
.build();
}
@Bean
public Step gameLoad(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("gameLoad", jobRepository)
.allowStartIfComplete(true)
.<String, String>chunk(10, transactionManager)
.reader(gameFileItemReader())
.writer(gameWriter())
.build();
}
@Bean
public Step playerSummarization(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("playerSummarization", jobRepository)
.startLimit(2)
.<String, String>chunk(10, transactionManager)
.reader(playerSummarizationSource())
.writer(summaryWriter())
.build();
}
以下 XML 示例显示了如何配置作业以具有可重启的步骤
<job id="footballJob" restartable="true">
<step id="playerload" next="gameLoad">
<tasklet>
<chunk reader="playerFileItemReader" writer="playerWriter"
commit-interval="10" />
</tasklet>
</step>
<step id="gameLoad" next="playerSummarization">
<tasklet allow-start-if-complete="true">
<chunk reader="gameFileItemReader" writer="gameWriter"
commit-interval="10"/>
</tasklet>
</step>
<step id="playerSummarization">
<tasklet start-limit="2">
<chunk reader="playerSummarizationSource" writer="summaryWriter"
commit-interval="10"/>
</tasklet>
</step>
</job>
前面的示例配置用于加载足球比赛信息并对其进行汇总的作业。它包含三个步骤:playerLoad
、gameLoad
和playerSummarization
。playerLoad
步骤从平面文件中加载球员信息,而gameLoad
步骤对游戏执行相同的操作。最后一步playerSummarization
根据提供的游戏汇总每个球员的统计数据。假设playerLoad
加载的文件必须只加载一次,但gameLoad
可以加载特定目录中找到的任何游戏,并在成功加载到数据库后将其删除。因此,playerLoad
步骤不包含任何其他配置。如果已完成则跳过它,可以启动任意次数。但是,gameLoad
步骤需要每次都运行,以防自上次运行以来添加了额外的文件。它将allow-start-if-complete
设置为true
以始终启动。(假设游戏加载到的数据库表上有一个进程指示器,以确保新的游戏可以被汇总步骤正确找到)。汇总步骤是作业中最重要的步骤,配置为启动限制为 2。这很有用,因为如果步骤持续失败,则会向控制作业执行的操作员返回新的退出代码,并且在进行手动干预之前,它无法再次启动。
此作业为此文档提供了一个示例,与示例项目中找到的footballJob 不同。 |
本节的其余部分描述了footballJob
示例的三个运行中的每一个都会发生的情况。
运行 1
-
playerLoad
运行并成功完成,向PLAYERS
表添加了 400 个玩家。 -
gameLoad
运行并处理了 11 个游戏数据文件,将其内容加载到GAMES
表中。 -
playerSummarization
开始处理,5 分钟后失败。
第二次运行
-
playerLoad
没有运行,因为它已经成功完成,并且allow-start-if-complete
为false
(默认值)。 -
gameLoad
再次运行并处理了另外 2 个文件,也将它们的内容加载到GAMES
表中(进程指示器表明它们尚未处理)。 -
playerSummarization
开始处理所有剩余的游戏数据(使用进程指示器进行过滤),并在 30 分钟后再次失败。
第三次运行
-
playerLoad
没有运行,因为它已经成功完成,并且allow-start-if-complete
为false
(默认值)。 -
gameLoad
再次运行并处理了另外 2 个文件,也将它们的内容加载到GAMES
表中(进程指示器表明它们尚未处理)。 -
playerSummarization
没有启动,作业立即被终止,因为这是playerSummarization
的第三次执行,而其限制次数只有 2 次。必须提高限制次数或将Job
作为新的JobInstance
执行。