高階元資料使用

JobRegistry

JobRegistry 用於跟蹤上下文中哪些作業可用,並可由 JobOperator 操作。它也適用於在應用程式上下文中集中收集作業,即使它們是在其他地方(例如,在子上下文)建立的。您還可以使用自定義 JobRegistry 實現來操作已註冊作業的名稱和其他屬性。框架只提供了一個實現,該實現基於從作業名稱到作業例項的簡單對映,即 MapJobRegistry

  • Java

  • XML

使用 @EnableBatchProcessing 時,會為您提供一個 MapJobRegistry。以下示例展示瞭如何配置您自己的 JobRegistry

...
@Bean
public JobRegistry jobRegistry() throws Exception {
	return new MyCustomJobRegistry();
}
...

以下示例展示瞭如何為 XML 中定義的作業包含 JobRegistry

<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

Spring Batch 提供的 MapJobRegistry 足夠智慧,可以自動填充應用程式上下文中所有作業。但是,如果您使用 JobRegistry 的自定義實現,則需要手動填充要透過作業操作器操作的作業。

JobParametersIncrementer

JobOperator 中的大多數方法都一目瞭然,您可以在介面的 Javadoc 中找到更詳細的解釋。但是,startNextInstance 方法值得注意。此方法始終啟動 Job 的新例項。如果 JobExecution 中存在嚴重問題並且需要從頭開始重新啟動 Job,這會非常有用。與 JobLauncher(它需要一個觸發新 JobInstance 的新 JobParameters 物件)不同,如果引數與任何以前的引數集不同,startNextInstance 方法使用繫結到 JobJobParametersIncrementer 來強制 Job 到一個新的例項

public interface JobParametersIncrementer {

    JobParameters getNext(JobParameters parameters);

}

JobParametersIncrementer 的契約是,給定一個 JobParameters 物件,它透過遞增其中可能包含的任何必要值來返回“下一個”JobParameters 物件。此策略很有用,因為框架無法知道對 JobParameters 的哪些更改使其成為“下一個”例項。例如,如果 JobParameters 中唯一的值是日期,並且應該建立下一個例項,那麼該值應該增加一天還是一週(例如,如果作業是每週執行的)?同樣,對於任何有助於識別 Job 的數值也可以這樣說,如下例所示

public class SampleIncrementer implements JobParametersIncrementer {

    public JobParameters getNext(JobParameters parameters) {
        if (parameters==null || parameters.isEmpty()) {
            return new JobParametersBuilder().addLong("run.id", 1L).toJobParameters();
        }
        long id = parameters.getLong("run.id",1L) + 1;
        return new JobParametersBuilder().addLong("run.id", id).toJobParameters();
    }
}

在此示例中,鍵為 run.id 的值用於區分 JobInstances。如果傳入的 JobParameters 為 null,則可以假定該 Job 從未執行過,因此可以返回其初始狀態。但是,如果不是,則獲取舊值,將其遞增 1,然後返回。

  • Java

  • XML

對於用 Java 定義的作業,您可以透過構建器中提供的 incrementer 方法將增量器與 Job 相關聯,如下所示

@Bean
public Job footballJob(JobRepository jobRepository) {
    return new JobBuilder("footballJob", jobRepository)
    				 .incrementer(sampleIncrementer())
    				 ...
                     .build();
}

對於在 XML 中定義的作業,您可以透過名稱空間中的 incrementer 屬性將增量器與 Job 相關聯,如下所示

<job id="footballJob" incrementer="sampleIncrementer">
    ...
</job>

停止作業

JobOperator 最常見的用例之一是優雅地停止作業

Set<Long> executions = jobOperator.getRunningExecutions("sampleJob");
jobOperator.stop(executions.iterator().next());

關閉不是立即的,因為無法強制立即關閉,特別是如果執行當前在開發人員程式碼中,而框架無法控制這些程式碼,例如業務服務。但是,一旦控制權返回給框架,它會將當前 StepExecution 的狀態設定為 BatchStatus.STOPPED,儲存它,並在完成之前對 JobExecution 執行相同的操作。

處理外部中斷訊號

從 v6.0+ 開始,Spring Batch 提供了一個 JobExecutionShutdownHook,您可以將其附加到 JVM 執行時,以攔截外部中斷訊號並優雅地停止作業執行

Thread springBatchHook = new JobExecutionShutdownHook(jobExecution, jobOperator);
Runtime.getRuntime().addShutdownHook(springBatchHook);

JobExecutionShutdownHook 需要跟蹤作業執行,以及對將用於停止執行的作業操作器的引用。

恢復作業

如果未正確執行優雅關閉(即 JVM 突然關閉),Spring Batch 將無法正確更新執行狀態以重新啟動失敗的作業執行。在這種情況下,作業執行將保持在 STARTED 狀態,該狀態不可重新啟動。在這種情況下,可以使用 JobOperator API 恢復此類作業執行

JobExecution jobExecution = ...; // get the job execution to recover
jobOperator.recover(jobExecution);
jobOperator.restart(jobExecution);

中止作業

狀態為 FAILED 的作業執行可以重新啟動(如果 Job 可重新啟動)。狀態為 ABANDONED 的作業執行不能由框架重新啟動。ABANDONED 狀態也用於步驟執行中,以將其標記為在重新啟動的作業執行中可跳過。如果作業正在執行並遇到在之前失敗的作業執行中標記為 ABANDONED 的步驟,它將繼續執行下一個步驟(由作業流定義和步驟執行退出狀態確定)。

如果程序死亡(kill -9 或伺服器故障),作業當然沒有執行,但 JobRepository 無法知道,因為在程序死亡之前沒有人告訴它。您必須手動告知它,您知道執行要麼失敗,要麼應該被視為中止(將其狀態更改為 FAILEDABANDONED)。這是一個業務決策,無法自動化。僅當可重新啟動且您知道重新啟動資料有效時,才將狀態更改為 FAILED

© . This site is unofficial and not affiliated with VMware.