在多个数据库上并行运行 Spring Batch

Posted

技术标签:

【中文标题】在多个数据库上并行运行 Spring Batch【英文标题】:Running Spring batch on multiple databases in parallel 【发布时间】:2017-11-10 02:38:30 【问题描述】:

我使用 Spring boot 创建了一个 Spring 批处理应用程序,并且我有一个包含 9 个步骤的 Job。这些步骤使用DataSource,我在配置文件中创建了它的bean,如下所示:

@Configuration
public class DatabaseConfig 
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    @Primary
    public DataSource dataSource()
        return DataSourceBuilder.create().build();
    

这个DataSource 正在使用application.yml 文件中声明的属性:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_01?zeroDateTimeBehavior=convertToNull
    username: xxxx
    password: ****

到目前为止,一切都按预期工作。

我想要做的是,我在第 5 个数据库 (db_settings) 中参数化了 4 个数据库,我使用 SQL 查询来选择这些数据库。此查询将返回 4 个数据库及其用户名和密码,如下所示:

+--------+-----------------------------------+-----------------+-----------------+
| id     | url                               | username_db     | password_db     |
+--------+-----------------------------------+-----------------+-----------------+
|    243 | jdbc:mysql://localhost:3306/db_01 | xxxx            | ****            |
|    244 | jdbc:mysql://localhost:3306/db_02 | xxxx            | ****            |
|    245 | jdbc:mysql://localhost:3306/db_03 | xxxx            | ****            |
|    247 | jdbc:mysql://localhost:3306/db_04 | xxxx            | ****            |
+--------+-----------------------------------+-----------------+-----------------+

因此,我不想使用“application.yml”中声明的数据库运行这些步骤,而是想在所有 4 个数据库上运行它们。 并且考虑到处理的量,有必要能够在这些数据库上并行启动批处理。

有人知道如何实现吗?

【问题讨论】:

我现在没有时间详细回答,但您可以结合两个简洁的功能来实现这一点:来自 Spring Batch 的分区作业 分区键是数据源 id 243、244 等) 和 Spring JDBC 中的 AbstractRoutingDataSource(它将从使用分区键初始化的作业参数中动态选择正确的数据源) @KeatsPeeks 很抱歉,我什么也得不到,如果您添加更多详细信息或代码示例,我将不胜感激。 【参考方案1】:

赏金在哪里? :-)


感谢 KeatsPeeks,AbstractRoutingDataSource 是解决方案的良好开端,这里是这部分的 good tutorial。

主要有以下重要部分:

    定义查找代码

public class MyRoutingDataSource extends AbstractRoutingDataSource @Override protected Object determineCurrentLookupKey() String language = LocaleContextHolder.getLocale().getLanguage(); System.out.println("Language obtained: "+ language); return language;

    注册多个数据源

    <bean id="abstractDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="$jdbc.driverClassName"
        p:username="$jdbc.username"
        p:password="$jdbc.password" />
    
    <bean id="concreteDataSourceOne"
        parent="abstractDataSource"
        p:url="$jdbc.databaseurlOne"/>
    
     <bean id="concreteDataSourceTwo"
        parent="abstractDataSource"
        p:url="$jdbc.databaseurlTwo"/>
    

那么之后,问题就变成了:

    如何在spring启动时加载datasource config属性,并使用数据库中的config属性配置对应的dataSource

    如何在spring批处理中使用多个dataSource

    其实我google的时候,好像这是最常见的情况,google给出的建议搜索词——“spring batch 多数据源”,文章很多,所以我选择答案在

    如何定义基于spring批处理作业的查找代码(步骤)

    通常这应该是一个业务点,您需要定义查找策略并可以注入com.example.demo.datasource.CustomRoutingDataSource#determineCurrentLookupKey 以路由到专用数据源。

限制

真正有趣的是它实际上支持多个dataSource,但数据库设置确实不能存储在数据库中。原因是它会得到循环依赖问题:

The dependencies of some of the beans in the application context form a cycle:

   batchConfiguration (field private org.springframework.batch.core.configuration.annotation.JobBuilderFactory com.example.demo.batch.BatchConfiguration.jobs)
      ↓
   org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration (field private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources)
┌─────┐
|  routingDataSource defined in class path resource [com/example/demo/datasource/DataSourceConfiguration.class]
↑     ↓
|  targetDataSources defined in class path resource [com/example/demo/datasource/DataSourceConfiguration.class]
↑     ↓
|  myBatchConfigurer (field private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources)
└─────┘

显然解决方案是打破dataSourceroutingDataSource之间的依赖关系

在属性中保存 DB 设置 或涉及其他方法但不在主要dataSource

另见

https://scattercode.co.uk/2013/11/18/spring-data-multiple-databases/ https://numberformat.wordpress.com/2013/12/27/hello-world-with-spring-batch-3-0-x-with-pure-annotations/

http://spring.io/guides/gs/batch-processing/

How to java-configure separate datasources for spring batch data and business data? Should I even do it?

Github 获取验证码。

【讨论】:

以上是关于在多个数据库上并行运行 Spring Batch的主要内容,如果未能解决你的问题,请参考以下文章

Spring Batch 并行读取数据库

Spring Batch -扩展和并行处理

Spring Batch - 如何使用一个读取其他步骤的作者的并行步骤?

《spring batch 批处理框架》第9、10、11章

Java Spring Batch:如何验证执行是并行完成的?

Spring batch 入门基础