Spring 批处理架构

Spring Batch architecture

我是 Spring Batch world 的新手,最近几天我花了一些时间观看 Michael Minella 的 youtube 视频,阅读了一些文档并成功 运行 我在互联网上找到的一些演示项目。我认为 Spring Batch 是满足我们需求的热门人选。但这是我们的故事。

我在一家公司工作,该公司在十多年前为他们的业务部门开发了自己的调度和批处理框架。该框架能够 运行ning 数据库存储过程、数据库函数和动态 SQL。不用说,维护它非常具有挑战性,因为太多具有各种开发技能的人进行了编码,他们不再在这里工作了。我们的框架可以按顺序处理 运行 的作业和步骤,也可以异步处理(如 Spring 批处理)。我们还有一个作业存储库,我们在其中存储整个作业定义(用户通过 GUI 创建新作业)、作业实例及其上下文(以防服务器出现故障,当服务器启动时它将恢复 运行ning 作业) . 我的问题如下:

  1. 我们能否动态创建新的 Spring 批处理作业(通过 XML og 代码)并通过标准 SB 接口将它们存储到 JobRepository 数据库中?

  2. 今天,在某个时间段,我们有多达数百个作业同时执行。他们还在重复使用数据库的连接池。 Older Spring Batch ref documentation 声明 JobFactory 将为每个作业执行创建新的 ApplicationContext。如果在 Spring Batch.

    中出现这种情况,我们如何实现重用连接池?
  3. 我知道支持继续失败的步骤,但是如果 server/app 出现故障,我是否能够重新启动我的应用程序并从 JobRepository 中检索作业实例及其上下文?为了从失败的步骤继续?

  4. “job1”中的“step1.1”能否依赖于“job2”中的“step 2.1”在最后一个小时内完成?在这种情况下,我可能会在“step1.1”上使用步骤侦听器来完成此操作?


亲切的问候

多多

Can we create new Spring Batch jobs dynamically (either via XML og code) and via standard SB interfaces store them the JobRepository DB?

很容易使用 StepBuilderFactoryFlowBuilder 等以编程方式构建 Spring 批处理工件。您可能希望使用 Spring Beans 支持这些工件(以获得像 step/job spring 范围、注入等不错的设施),为此您可以使用原型、执行范围和作业范围的 beans,甚至使用 BeanDefinitionBuilder 等工具来动态创建 beans。

Older Spring Batch ref documentation states JobFactory will create fresh ApplicationContext for each job execution. How can we achieve reusing connection pools if this is the case in Spring Batch.

GenericApplicationContextFactory 创建子应用程序上下文。您可以在父应用程序上下文中拥有 "global" 个 bean。

I know there is a support for continuing failed steps but what if the server/app goes down, will I be able to restart my app and retrieve job instance with its context from JobRepository in order to continue from failed step?

是的,但是 not that easily

Can a "step1.1" in "job1" be dependent on "step 2.1" from "job2" finishing within last hour? In such scenarios I may be using a step listener on "step1.1" to accomplish this?

JobExecutionDecider 可能是最好的选择。

这里有很多material要讲,所以让我一次回复一个点:

我们能否动态创建新的 Spring 批处理作业(通过 XML 或代码)并通过标准 SB 接口将它们存储到 JobRepository DB?

能否动态生成作业定义?是的。我们在 Spring XD 中针对作业编排部分执行此操作(例如,组合作业 DSL 用于生成 XML 文件。

Spring Batch 是否提供执行此操作的工具?不,您必须自己编写代码。

另请注意,您必须将定义存储在自己的 table 中(由 Spring Batch 定义的架构没有 table)。

今天,在某个时间段,我们有多达数百个作业同时执行。他们还在重复使用数据库的连接池。较旧的 Spring 批处理参考文档指出 JobFactory 将为每个作业执行创建新的 ApplicationContext。如果在 Spring Batch.

中出现这种情况,我们如何实现重用连接池?

您可以使用 parent/child 上下文配置来重用包含 DataSource 的 bean。在父上下文中定义 DataSource,然后在子上下文中定义依赖于它的作业。

我知道支持继续失败的步骤,但是如果 server/app 出现故障,我是否能够重新启动我的应用程序并从 JobRepository 中检索作业实例及其上下文?为了从失败的步骤继续?

这确实是一个编排问题。 Spring 批处理在设计上并未考虑作业的编排问题。这使您可以按照自己的意愿编排它们。

我推荐的处理方式是通过 Spring XD or (depending on your timelines) Spring Cloud Data Flow。这些工具提供编排功能,包括在作业出现故障时重新部署作业。话虽如此,如果它失败,它不会重新启动 运行 的作业,因为这通常需要基于用例的某种形式的人为决定。然而,Spring XD 目前(Spring Cloud Data Flow 将)有能力以非常直接的方式实现类似的东西。

"job1" 中的 "step1.1" 能否依赖于 "job2" 中的 "step 2.1" 在最后一小时内完成?在这种情况下,我可能会在 "step1.1" 上使用步骤侦听器来完成此操作?

在这种情况下,我会开始质疑你的工作是如何配置的。您可以使用 JobExecutionDecider 来决定是否应该执行某个步骤(如果它仍然有意义)。

考虑到所有因素,虽然您可以使用 Spring Batch 完成您正在寻找的大部分内容,但使用 Spring XD 或 Spring Cloud Data Flow 之类的东西将使您生活轻松多了。