运行 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.