当前位置: 首页 > 知识库问答 >
问题:

Spring Batch:作业存储库的水平扩展

孙书
2023-03-14

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

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

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

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

我认为JobRepository的所有实例都将共享相同的模式,因此它们都可以查询状态当前何时处于处理中并决定它们将做什么。不过,我不确定这个模式或JobRepository实现是否意味着被多个实例使用。

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

共有2个答案

琴英华
2023-03-14

以下摘自Spring Batch文档,介绍Spring Batch如何处理其存储库的数据库更新:

Spring Batch在处理数据库更新时采用乐观锁定策略。这意味着每次“触摸”(更新)一条记录时,版本列中的值都会增加1。当存储库返回保存值时,如果版本号已更改,它会抛出一个乐观锁定失败异常,指示并发访问出现错误。此检查是必要的,因为即使不同的批处理作业可能在不同的机器上运行,它们都使用相同的数据库表。

唐高卓
2023-03-14

我决定构建一个原型来测试Spring Batch作业存储库模式和SimpleJobRepository是否可以以负载平衡的方式使用多个Spring BatchJava进程并发运行的条件。我担心死锁场景可能发生在数据库中,所有正在运行的作业进程都被卡住了。

我从mkyong-Spring-Batch-HelloWorld示例开始,对其进行了一些更改,可以将其打包到一个Jar中,并可以从命令行执行。我还删除了数据库中定义的初始化数据库步骤。配置文件并手动建立一个具有适当模式元素的本地MySQL服务器。我为时间添加了一个作业参数,以毫秒为单位表示当前时间,以便每个作业实例都是唯一的。

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

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

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

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

 类似资料:
  • 我已经开始探索Spring Batch,并遇到了一些基本问题。

  • 我正在创建一个由groovy bean builder支持的spring批处理(spring boot)。但是,我无法找到以下xml结构的正确语法: 更新:豆子。棒极了 我想使用选项1技术,如果我这样做,我会得到“beanName must not empty”错误。我没有使用选项2中的bean,而是它们似乎在工作。 我假设使用选项1,将使用其他定义的bean自动配置jobRepository等。

  • 用例:步骤1:ItemReader:从数据库中读取1000个ItemProcessor块中的数据:处理这些数据。ItemWriter:将数据写入地图,以便下一步使用 步骤2:ItemReader:读取地图ItemProcessor:处理地图数据并获取新对象。ItemWriter:将新的进程对象持久化到数据库中。 现在我希望Map在整个作业中保持不变,目前我已经为Map创建了一个不同的POJO类,并

  • 我已经实现了Spring数据存储库,它使用注释扩展MongoRepository,将它们标记为RESTendpoint。但当映射请求id时,会得到以下异常 存储库: GET 请求我正在尝试: 回应: 另外,我为每个存储库配置了两个数据库。 Application.yml文件: 主要类 : 这里会出什么问题?

  • 现在我手动更改系统时间。例如,如果我将作业安排在2/5/2013 12:45 PM运行,那么我将系统时钟时间更改为2/5/2013 12:43 PM,然后等待几分钟,看看Quartz是否从DB接收到该作业。这对我很管用。 我不想每次需要测试时都更改系统时钟时间。有没有更好的办法做到这一点? 我注意到频繁地改变系统时间有时会使Quartz搞砸,因为有些工作没有被接上。

  • 本文向大家介绍SQL SERVER数据库的作业的脚本及存储过程,包括了SQL SERVER数据库的作业的脚本及存储过程的使用技巧和注意事项,需要的朋友参考一下 用系统存储过程去创建作业,代码如下: Transact-SQL 参考 本站文章旨在为该问题提供解决思路及关键性代码,并不能完成应该由网友自己完成的所有工作,请网友在仔细看文章并理解思路的基础上举一反三、灵活运用。