為重新啟動配置 Step
在“配置和執行 Job”一節中,我們討論了重新啟動 Job。重啟對步驟有諸多影響,因此可能需要一些特定的配置。
設定啟動限制
在許多場景中,您可能希望控制 Step 可以啟動的次數。例如,您可能需要配置一個特定的 Step,使其只執行一次,因為它會使某些資源失效,這些資源在再次執行之前必須手動修復。這可以在步驟級別進行配置,因為不同的步驟可能有不同的要求。一個只能執行一次的 Step 可以與一個可以無限執行的 Step 作為同一個 Job 的一部分存在。
-
Java
-
XML
以下程式碼片段展示了 Java 中啟動限制配置的示例
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(10).transactionManager(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(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(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(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(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 分鐘後失敗。
第 2 次執行
-
playerLoad不執行,因為它已成功完成,並且allow-start-if-complete為false(預設值)。 -
gameLoad再次執行並處理另外 2 個檔案,也將其內容載入到GAMES表中(帶有一個指示尚未處理的程序指示器)。 -
playerSummarization開始處理所有剩餘的比賽資料(使用程序指示器進行過濾)並在 30 分鐘後再次失敗。
第 3 次執行
-
playerLoad不執行,因為它已成功完成,並且allow-start-if-complete為false(預設值)。 -
gameLoad再次執行並處理另外 2 個檔案,也將其內容載入到GAMES表中(帶有一個指示尚未處理的程序指示器)。 -
playerSummarization未啟動,作業立即終止,因為這是playerSummarization的第三次執行,其限制僅為 2。必須提高限制,或者將Job作為新的JobInstance執行。