Spring boot 2.4.x 无法处理来自配置服务器的多文档 yml 文件

Posted

技术标签:

【中文标题】Spring boot 2.4.x 无法处理来自配置服务器的多文档 yml 文件【英文标题】:Spring boot 2.4.x cannot handle multi document yml files from config server 【发布时间】:2021-04-19 11:36:40 【问题描述】:
    Java 版本:8 Spring Boot 版本:2.4.1 Spring Cloud 版本:2020.0.0,具体来说我使用的是一个连接到 GIT 的 Spring Cloud Config Server,我们的服务是 Spring Cloud Config Clients。

我已不再使用bootstrap.yml,而是开始使用spring.config.importspring.config.activate.on-profile,如文档here 和here 中所述

我的服务中的配置,作为配置服务器的客户端,如下所示:

server.port: 9001
spring:
  application.name: my-rest-service
  config.import: configserver:http://localhost:8888
  cloud.config.profile: $spring.profiles.active

我在配置服务器中的配置如下:

application.yml(有两个文件由---分隔)

logging:
  file.name: <omitted>
  level:
    root: INFO
---
spring:
  config.activate.on-profile: dev
  logging.level.root: DEBUG

my-rest-sercive.yml(有两个文件由 --- 分隔)

spring:
  datasource:
    driver-class-name: <omitted>
    username: <omitted>
    password: <omitted>
---
spring:
  config.activate.on-profile: dev
  datasource.url: <omitted>

因为有一个配置文件“dev”处于活动状态,所以我成功地从配置服务器获取了以下 4 个配置:

application.yml:一般日志记录级别 application.yml:开发人员的特定日志记录 my-rest-sercive.yml:通用数据源属性 my-rest-sercive.yml: dev 的特定数据源 url

当我使用浏览器或调试时,或者当我降低日志级别进行跟踪时,我可以看到这 4 个源被成功获取:

o.s.b.c.config.ConfigDataEnvironment     : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment     : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\my-rest-service.yml'
o.s.b.c.config.ConfigDataEnvironment     : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'
o.s.b.c.config.ConfigDataEnvironment     : Adding imported property source 'configserver:https://git.company.com/path.git/file:C:\configservergit\config\application.yml'

但是,请注意,由于我使用多文档 yml 文件,因此在这 4 个属性源中,仅使用了两个唯一名称。

在后面的步骤中,当 Spring 创建数据源 bean 时,他抱怨找不到数据源 URL。如果我调试 spring bean 工厂,我确实可以看到配置服务器返回的 4 个属性文件中,只剩下两个(不包含 dev profile 特定配置的那些)。我认为这是因为它们具有相同的名称并且它们相互覆盖。这是MutablePropertySource.class中这段代码的效果:

public void addLast(PropertySource<?> propertySource) 
    synchronized(this.propertySourceList) 
        this.removeIfPresent(propertySource); <-- this is the culrprit!
        this.propertySourceList.add(propertySource);
    
 

这是 Spring 2.3/Spring Cloud Hoxton 的重大变化,它正确收集了所有属性。我认为 Spring Cloud 需要更改配置服务器,以便 yml 中的每个文档在返回 Spring 时都有一个唯一的名称。这正是 Spring Boot 处理多文档 yml 文件的方式,通过将字符串 (documenyt #1) 附加到属性源名称

我发现an interesting note 关于配置文件和多文档 yml,基本上说它不受支持,但这不适用于我的用例,因为我的 yml 文件不是基于配置文件的(最后没有 -profileName文件名的一部分)。

【问题讨论】:

究竟是什么问题?你想克服这个问题吗?我觉得最好在spring cloud仓库提一个issue,并附上你的调查结果。 @amseager 是的,你是对的。这似乎是一个已知问题,我将这个问题链接到它。 【参考方案1】:

这是新版本的一个已知问题。我们可以在the spring cloud config server github page 跟踪问题。

解决方法似乎是停止使用多文档 yml 文件并使用文件名中包含配置文件名称的多个不同文件。

【讨论】:

以上是关于Spring boot 2.4.x 无法处理来自配置服务器的多文档 yml 文件的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot Maven 插件 > 2.4.x 在 gitlab 注册表上构建映像发布

Spring Boot 自动配置无法与 spring-data-jpa 一起正常工作

Kotlin Spring Boot 注解处理“无法解析配置处理”

Spring Boot 2.6.1 正式发布,2.4.x Game Over,2.5.0 成最低支持版本。。

Spring Boot Async 方法如何使用 ThreadPool 处理请求

无法在 Spring Boot 中启动嵌入式 Tomcat [重复]