Spring Batch:作业存储库的水平伸缩 [英] Spring Batch: Horizontal scaling of Job Repository

查看:18
本文介绍了Spring Batch:作业存储库的水平伸缩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到了很多关于如何使用Master/Slave范型启用单个作业的并行处理和分块的内容。考虑一个已经实现的Spring Batch解决方案,该解决方案打算在独立服务器上运行。通过最小限度的重构,我希望使其能够横向扩展,并在生产操作中具有更强的弹性。速度和效率不是目标。

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

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

单点故障是作业启动的单个服务器和单个侦听进程。我希望通过水平扩展相同的服务器实例来提高弹性,所有服务器实例都在争夺作业启动消息第一次出现在队列中时谁能最先捕获它。该服务器实例现在将尝试运行该作业。

我设想JobRepository的所有实例都将共享相同的模式,这样它们都可以查询当前正在处理的状态,并决定它们将执行什么操作。不过,我不确定此架构或JobRepository实现是否要由多个实例使用。

执行此操作是否存在此方法可能导致数据库死锁的风险?Spring Batch的分区功能在哪些地方不适用于我的应用程序,还有其他限制。

推荐答案

我决定构建一个原型来测试Spring Batch Job Repository模式和SimpleJobRepository是否可以负载平衡的方式与多个Spring Batch Java进程并发运行。我担心所有正在运行的作业进程都会停滞的数据库中可能发生了死锁情况。

我的测试

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

接下来,我编写了一个单独的Java主类,它使用Apache Commons Exec框架创建了50个子进程,它们之间无需等待。这些进程中的每个进程在其处理器对象中也都有一个1秒的Thread.sleep,以便多个进程都将同时启动,并且所有进程都会同时尝试访问数据库。

结果

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

因此,听起来似乎没有使用高级主/从和步骤分区方法的Spring批处理作业的负载平衡是一个有效的用例。

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

这篇关于Spring Batch:作业存储库的水平伸缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆