Spring 批处理 : Horizontal scaling of Job Repository

标签 spring spring-batch

我读了很多关于如何使用主/从范例启用并行处理和单个作业分块的内容。考虑一个已经实现的 Spring Batch 解决方案,该解决方案旨在在独立服务器上运行。通过最少的重构,我希望能够水平扩展并在生产操作中更具弹性。速度和效率不是目标。

http://www.mkyong.com/spring-batch/spring-batch-hello-world-example/

在以下示例中,使用作业存储库连接到并初始化作业存储库的数据库架构。作业启动请求被馈送到消息队列,具有单个 Java 进程的单个服务器通过 Spring JMS 进行监听。当遇到这种情况时,它会执行一个新的 Java 进程,即 Spring Batch 作业。如果作业尚未根据作业存储库启动,它将开始。如果作业失败,它将从作业中断的地方继续。如果作业正在进行中,它将被忽略。

单点故障是作业启动的单个服务器和单个监听进程。我想通过水平扩展相同的服务器实例来提高弹性,所有实例都竞争谁可以在作业启动消息首次出现在队列中时首先获取作业启动消息。该服务器实例现在将尝试运行该作业。

我设想 JobRepository 的所有实例都将共享相同的架构,因此它们都可以查询当前状态何时处于处理状态并决定它们将做什么。但我不确定此架构或 JobRepository 实现是否旨在由多个实例使用。

采用这种方法是否存在导致数据库死锁的风险? Spring Batch 的分区功能在我的应用程序中不起作用还存在其他限制。

最佳答案

我决定构建一个原型(prototype)来测试 Spring Batch Job Repository 架构和 SimpleJobRepository 是否可以以负载平衡的方式使用多个并发运行的 Spring Batch Java 进程。我担心数据库可能会出现死锁情况,导致所有正在运行的作业进程都卡住。

我的测试

我从 mkyong Spring Batch HelloWorld 示例开始,对其进行了一些更改,可以将其打包到可以从命令行执行的 Jar 中。我还删除了在database.config 文件中定义的初始化数据库步骤,并使用正确的架构元素手动建立了本地MySQL 服务器。我为 time 添加了一个作业参数,使其成为当前时间(以毫秒为单位),以便每个作业实例都是唯一的。

接下来,我编写了一个单独的 Java 主类,它使用 Apache Commons Exec 框架创建 50 个子进程,并且子进程之间没有等待。每个进程在其 Processor 对象内都有一个 Thread.sleep 1 秒,以便多个进程同时启动并尝试同时访问数据库。

结果

连续多次运行此测试后,我发现所有 50 个 Spring 批处理进程始终成功完成并正确更新相同的数据库架构。我没有看到任何迹象表明,如果有多个 Spring Batch 作业进程在连接到同一数据库的多个服务器上运行,它们会在架构上相互干扰,也没有看到任何迹象表明此时可能会发生死锁。

因此,听起来好像不使用高级主/从和步骤分区方法的 Spring Batch 作业负载平衡是一个有效的用例。

如果有人想对我的测试发表评论或提出改进方法,我将不胜感激。

关于 Spring 批处理 : Horizontal scaling of Job Repository,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34336880/

相关文章:

java - spring-batch-integration 1.2.2 与 spring-batch 2.2.2 不兼容

java - Spring Batch header 处理程序问题

java - 将 lineNumber 存储在 stepExecutionContext 中并访问它

spring-boot - 定义内存中的 JobRepository

java - Spring MVC 在 "/"上打开 index.jsp

Java 表达式解析获取对象

hibernate - 使用 Spring 3.1 和 Hibernate 4 时替换 IdTransferringMergeEventListener

spring - 使用 Spring Batch 解析多个 csv 文件

spring - 如何在同一个 bean 中 Autowiring bean

java - 基于@Aspectj的AOP : Advice is not getting called