Spring Cloud Data Flow 忽略由 spring 批处理应用程序配置的数据源

Posted

技术标签:

【中文标题】Spring Cloud Data Flow 忽略由 spring 批处理应用程序配置的数据源【英文标题】:Spring Cloud Data Flow ignores datasources configured by a spring batch app 【发布时间】:2019-12-07 06:11:54 【问题描述】:

我正在设置 Spring Cloud Data Flow 的一个实例。我已经运行了以下命令:

1. Run skipper server: java -jar spring-cloud-skipper-server-2.0.3.RELEASE.jar &
2. Run Dataflow server: java -jar spring-cloud-dataflow-server-2.1.2.RELEASE.jar \
    --spring.datasource.url=jdbc:postgresql://10.136.66.44:8080/springclouddataflow \
    --spring.datasource.username=springclouddataflow \
    --spring.datasource.password=123456 \
    --spring.datasource.driver-class-name=org.postgresql.Driver \
    --server.port=80 &

在第二步中,我使用的是 postgres 数据库,而不是默认的 h2。

我已经使用 Spring Batch 开发了一个 Spring Boot 作业以部署在这个平台中。该作业使用两个数据源:用于 Spring 的 springclouddataflow 和用于我的业务逻辑的 task Metadata 和 billrun。当我在本地运行应用程序时,它按预期将元数据保存在 springclouddataflow 中,并将我的业务数据保存在 billrun 中。 问题是当我尝试在 Spring Cloud Dataflow 中执行 de 作业时。平台忽略了我配置的业务逻辑数据库,只使用了 springclouddataflow 数据库,它应该只存储元数据。

我搜索过官方documentation。它解释了如何使用不同的数据库进行元数据存储以及如何在应用程序中配置多个数据库。我已按照说明进行操作,但没有成功。

application.properties

logging.level.org.springframework.cloud.task=debug
spring.datasource.initialization-mode=always
spring.batch.initialize-schema=always
spring.application.name=Bill Run
spring.datasource.jdbc-url=jdbc:postgresql://10.136.66.44:8080/springclouddataflow?useSSL=false
spring.datasource.username=springclouddataflow
spring.datasource.password=123456
spring.datasource.driver-class-name=org.postgresql.Driver
app.datasource.jdbc-url=jdbc:postgresql://10.136.66.44:8080/billrun?useSSL=false
app.datasource.username=springclouddataflow
app.datasource.password=123456
app.datasource.driver-class-name=org.postgresql.Driver

数据源配置

@Configuration
public class DatasourceConfiguration 
    @Bean(name = "appDatasource")
    @ConfigurationProperties(prefix = "app.datasource")
    public DataSource sourceDataSource() 
        return DataSourceBuilder.create().build();
    

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource springDataSource() 
        return DataSourceBuilder.create().build();
    

    @Bean
    public TaskConfigurer taskConfigurer() 
        return new DefaultTaskConfigurer(springDataSource());
    

计费配置

@Configuration
@EnableTask
@EnableBatchProcessing
public class BillingConfiguration 
    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Value("$usage.file.name:classpath:usageinfo.json")
    private Resource usageResource;

    @Bean
    public Job job1(ItemReader<Usage> reader, ItemProcessor<Usage, Bill> itemProcessor, ItemWriter<Bill> writer) 
        Step step = stepBuilderFactory.get("BillProcessing").<Usage, Bill>chunk(1).reader(reader)
                .processor(itemProcessor).writer(writer).build();

        return jobBuilderFactory.get("BillJob").incrementer(new RunIdIncrementer()).start(step).build();
    

    @Bean
    public JsonItemReader<Usage> jsonItemReader() 

        ObjectMapper objectMapper = new ObjectMapper();
        JacksonJsonObjectReader<Usage> jsonObjectReader = new JacksonJsonObjectReader<>(Usage.class);
        jsonObjectReader.setMapper(objectMapper);

        return new JsonItemReaderBuilder<Usage>().jsonObjectReader(jsonObjectReader).resource(usageResource)
                .name("UsageJsonItemReader").build();
    

    @Bean
    public ItemWriter<Bill> jdbcBillWriter(@Qualifier("appDatasource") DataSource dataSource) 
        JdbcBatchItemWriter<Bill> writer = new JdbcBatchItemWriterBuilder<Bill>().beanMapped().dataSource(dataSource)
                .sql("INSERT INTO BILL_STATEMENTS (id, first_name, "
                        + "last_name, minutes, data_usage,bill_amount) VALUES "
                        + "(:id, :firstName, :lastName, :minutes, :dataUsage, " + ":billAmount)")
                .build();
        return writer;
    

    @Bean
    ItemProcessor<Usage, Bill> billProcessor() 
        return new BillProcessor();
    

我尝试将数据库属性作为参数传递给任务:

当我查看数据源时,springclouddataflow 中只有数据持久化。如何告诉 Spring Cloud 数据流使用我的应用程序数据源 (billrun)?

【问题讨论】:

【参考方案1】:

您似乎正在自定义 Spring Cloud Data Flow 服务器以使用我认为不需要的应用程序数据源。

您可以像上面发布的那样启动您的 SCDF 服务器:

1. Run skipper server: java -jar spring-cloud-skipper-server-2.0.3.RELEASE.jar &
2. Run Dataflow server: java -jar spring-cloud-dataflow-server-2.1.2.RELEASE.jar \
    --spring.datasource.url=jdbc:postgresql://10.136.66.44:8080/springclouddataflow \
    --spring.datasource.username=springclouddataflow \
    --spring.datasource.password=123456 \
    --spring.datasource.driver-class-name=org.postgresql.Driver \
    --server.port=80 &

并且,让您的 Spring 批处理应用程序将其数据源属性作为 Spring Boot 属性传递,而不是像上面那样使用自定义数据源配置。

您可以使用类似的方法找到 Spring Batch 应用程序开发指南here

【讨论】:

我需要这种“自定义”,因为我必须将我的元数据存储在 Spring Cloud 数据库中,并将我的业务数据存储在应用程序数据库中。文档中建议的方法为元数据和业务逻辑配置单个数据库。如何为我的春季批处理任务传递第二个数据库?我尝试将作为参数传递给任务(弹簧启动配置),但它不起作用。 我已经完成了另一个测试,将数据库属性作为参数传递,它成功了!非常感谢您的帮助!【参考方案2】:

只需尝试在应用程序中添加动态数据源,如下所示,然后在需要的地方自动连接动态数据源

@Configuration
public class DataSourceConfig 

    @Bean(name = "testingDataSource")    
    @ConfigurationProperties(prefix = "testing.datasource") 
    public DataSource testDataSource()  
        return DataSourceBuilder.create().build(); 
    
    
    
    @Bean(name = "testingJdbcTemplate") 
    public JdbcTemplate testJdbcTemplate(@Qualifier("testingDataSource") DataSource dsmysql) 
        return new JdbcTemplate(dsMySQL);
    
    

测试: 数据源: driverClassName: 'com.mysql.cj.jdbc.Driver' jdbc-url: 'jdbc:mysql://localhost/dbName' 用户名:'uname' 密码:'密码'

【讨论】:

以上是关于Spring Cloud Data Flow 忽略由 spring 批处理应用程序配置的数据源的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud Data Flow参考指南

Swarm 的 Spring Cloud Data Flow 支持

Spring Cloud Data Flow 的自定义任务中缺少参数

Spring Cloud Data Flow 安全配置和与 RedHat SSO 的集成

Spring Cloud Data Flow 编辑现有流

Spring Cloud Data Flow Grafana Prometheus 不显示流数据