執行 Job

至少,啟動一個批處理作業需要兩件事:要啟動的 Job 和一個 JobOperator。兩者可以包含在相同或不同的上下文中。例如,如果您從命令列啟動作業,則會為每個 Job 例項化一個新的 JVM。因此,每個作業都有自己的 JobOperator。但是,如果您在 HttpRequest 範圍內從 Web 容器內部執行,通常有一個 JobOperator(配置為非同步作業啟動)供多個請求呼叫以啟動其作業。

從命令列執行作業

如果您想從企業排程程式執行作業,命令列是主要介面。這是因為大多數排程程式(除了 Quartz,除非使用 NativeJob)直接與作業系統程序一起工作,主要透過 shell 指令碼啟動。除了 shell 指令碼,還有許多方法可以啟動 Java 程序,例如 Perl、Ruby,甚至構建工具,例如 Ant 或 Maven。但是,由於大多數人熟悉 shell 指令碼,因此本示例將重點關注它們。

CommandLineJobOperator

由於啟動作業的指令碼必須啟動 Java 虛擬機器,因此需要一個帶有 main 方法的類作為主要入口點。Spring Batch 提供了一個實現來滿足此目的:CommandLineJobOperator。請注意,這只是引導應用程式的一種方式。啟動 Java 程序的方法有很多種,不應將此類視為最終定義。CommandLineJobOperator 執行四個任務

  • 載入適當的 ApplicationContext

  • 將命令列引數解析為 JobParameters

  • 根據引數找到適當的作業。

  • 使用應用程式上下文中提供的 JobOperator 啟動作業。

所有這些任務都僅透過傳入的引數完成。下表描述了所需的引數

表 1. CommandLineJobOperator 引數

jobClass

用於建立 ApplicationContext 的作業配置類的完全限定名稱。此檔案應包含執行完整 Job 所需的一切,包括 JobOperatorJobRepository 和填充了要操作的作業的 JobRegistry

operation

要在作業上執行的操作名稱。可以是 [start, startNextInstance, stop, restart, abandon] 之一

jobNamejobExecutionId

根據操作,這可以是要啟動的作業名稱,也可以是要停止、重新啟動、放棄或恢復的作業的執行 ID。

啟動作業時,這些引數之後的所有引數都被視為作業引數,並轉換為 JobParameters 物件,並且必須採用 name=value,type,identifying 的格式。在停止、重新啟動、放棄或恢復作業的情況下,jobExecutionId 預計為第 4 個引數,所有剩餘引數都將被忽略。

以下示例顯示了作為作業引數傳遞給 Java 中定義的作業的日期

<bash$ java CommandLineJobOperator io.spring.EndOfDayJobConfiguration start endOfDay schedule.date=2007-05-05,java.time.LocalDate

預設情況下,CommandLineJobOperator 使用 DefaultJobParametersConverter,它將鍵/值對隱式轉換為標識作業引數。但是,您可以透過分別使用 truefalse 作為字尾來明確指定哪些作業引數是標識性的,哪些不是。

在以下示例中,schedule.date 是標識作業引數,而 vendor.id 不是

<bash$ java CommandLineJobOperator io.spring.EndOfDayJobConfiguration start endOfDay \
                                 schedule.date=2007-05-05,java.time.LocalDate,true \
                                 vendor.id=123,java.lang.Long,false

您可以透過在 CommandLineJobOperator 上設定自定義 JobParametersConverter 來覆蓋此行為。

退出程式碼

從命令列啟動批處理作業時,通常會使用企業排程程式。大多數排程程式都相當簡單,只在程序級別工作。這意味著它們只瞭解某些作業系統程序(例如它們呼叫的 shell 指令碼)。在這種情況下,向排程程式傳達作業成功或失敗的唯一方法是透過返回碼。返回碼是一個數字,由程序返回給排程程式,以指示執行結果。在最簡單的情況下,0 表示成功,1 表示失敗。但是,可能存在更復雜的場景,例如“如果作業 A 返回 4,則啟動作業 B;如果作業 B 返回 5,則啟動作業 C。” 這種行為在排程程式級別配置,但重要的是,像 Spring Batch 這樣的處理框架提供一種方法來返回特定批處理作業的退出程式碼的數字表示。在 Spring Batch 中,這封裝在 ExitStatus 中,第 5 章將更詳細地介紹。就討論退出程式碼而言,唯一重要的事情是 ExitStatus 具有由框架(或開發人員)設定的退出程式碼屬性,並作為從 JobOperator 返回的 JobExecution 的一部分返回。CommandLineJobOperator 透過使用 ExitCodeMapper 介面將此字串值轉換為數字

public interface ExitCodeMapper {

    int intValue(String exitCode);

}

ExitCodeMapper 的基本約定是,給定一個字串退出程式碼,將返回一個數字表示。作業執行器使用的預設實現是 SimpleJvmExitCodeMapper,它返回 0 表示完成,1 表示通用錯誤,2 表示任何作業執行器錯誤,例如無法在提供的上下文中找到 Job。如果需要比上述三個值更復雜的內容,則必須透過在 CommandLineJobOperator 上設定自定義的 ExitCodeMapper 介面實現。

從 Web 容器內部執行作業

歷史上,離線處理(例如批處理作業)是從命令列啟動的,如前所述。但是,在許多情況下,從 HttpRequest 啟動是更好的選擇。許多此類用例包括報告、即席作業執行和 Web 應用程式支援。由於批處理作業(根據定義)是長時間執行的,因此最重要的是非同步啟動作業

Async Job Launcher Sequence from web container
圖 1. 從 Web 容器非同步啟動作業序列

在這種情況下,控制器是 Spring MVC 控制器。有關 Spring MVC 的更多資訊,請參閱 Spring 框架參考指南。控制器透過使用配置為 非同步 啟動的 JobOperator 來啟動 Job,該 JobOperator 立即返回 JobExecutionJob 很可能仍在執行。但是,這種非阻塞行為允許控制器立即返回,這在處理 HttpRequest 時是必需的。以下清單顯示了一個示例

@Controller
public class JobOperatorController {

    @Autowired
    JobOperator jobOperator;

    @Autowired
    Job job;

    @RequestMapping("/jobOperator.html")
    public void handle() throws Exception{
        jobOperator.start(job, new JobParameters());
    }
}
© . This site is unofficial and not affiliated with VMware.