【问题标题】:Spring Cloud Server serving multiple property files for the same applicationSpring Cloud Server 为同一个应用程序提供多个属性文件
【发布时间】:2019-07-02 20:54:57
【问题描述】:

假设我的应用程序 A 有 3 个属性文件:

-> applicationA
          - datasource.properties
          - security.properties
          - jms.properties

如何将所有属性移动到 Spring Cloud 服务器并保持独立?

截至今天,我已经配置了只读取一个属性文件的配置服务器,因为这似乎是标准方式。配置服务器获取的这个文件似乎是通过使用 spring.application.name 来解决的。就我而言,它只会读取一个具有此名称的文件:

-> applicationA.properties

如何添加配置服务器解析的其他文件?

【问题讨论】:

  • 你能澄清你的问题吗?您是否希望配置服务器将 3 个文件(即数据源、安全性和 jms .properties)发送回客户端应用程序?

标签: spring-cloud-config


【解决方案1】:

按照您要求的方式不可能。 Spring Cloud Config Server 使用 NativeEnvironmentRepository,即:

使用 SpringApplication 和通过普通协议定位的配置文件的 {@link EnvironmentRepository} 的简单实现。生成的环境由使用应用程序名称作为配置文件主干 (spring.config.name) 和环境名称作为 Spring 配置文件定位的属性源组成。

见:https://github.com/spring-cloud/spring-cloud-config/blob/master/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentRepository.java

所以基本上每次客户端从 Config Server 请求属性时,它都会使用 SpringApplicationBuilder 创建 ConfigurableApplicationContext。它使用下一个配置属性启动:

String config = application;
if (!config.startsWith("application")) {
    config = "application," + config;
}
list.add("--spring.config.name=" + config);

因此,属性文件的可能名称将只有 application.properties(or .yml) 和请求配置的配置客户端应用程序名称 - 在您的情况下为 applicationA.properties

但你可以“作弊”。 在配置服务器配置中,您可以添加此类属性

spring:
  cloud:
    config:
      server:
        git:
          search-paths: '{application}, {application}/your-subdirectory'

在这种情况下,配置服务器将搜索相同的属性文件名,但在几个目录中,您可以使用子目录来保持您的属性分开。 因此,通过上面的配置,您将能够从以下位置加载配置:

applicationA/application.properies
applicationA/your-subdirectory/application.properies

【讨论】:

    【解决方案2】:

    这是可以做到的。 您需要创建自己的 EnvironmentRepository,它会加载您的属性文件。

    org.springframework.cloud.config.server.support.AbstractScmAccessor#getSearchLocations 搜索要加载的属性文件:

    for (String prof : profiles) {
                for (String app : apps) {
                    String value = location;
                    if (app != null) {
                        value = value.replace("{application}", app);
                    }
                    if (prof != null) {
                        value = value.replace("{profile}", prof);
                    }
                    if (label != null) {
                        value = value.replace("{label}", label);
                    }
                    if (!value.endsWith("/")) {
                        value = value + "/";
                    }
                    output.addAll(matchingDirectories(dir, value));
                }
            }
    

    您可以在此处添加自定义代码,以读取所需的属性文件。 上面的代码与 spring 文档中描述的行为完全匹配。 NativeEnvironmentRepository 不会以任何方式访问 GIT/SCM,因此您应该使用 JGitEnvironmentRepository 作为您自己实现的基础。

    【讨论】:

      【解决方案3】:

      正如@nmyk 指出的那样,NativeEnvironmentRepository 启动一个迷你应用程序,以便通过向它提供 - 有点说 - “硬编码”{appname}.* 和 application.* 支持的属性文件名。 (@Stefan Isele - prefabware.com JGitEnvironmentRepository 最终也使用 NativeEnvironmentRepository)。

      我已经发布了一个pull request for spring-cloud-config-server 1.4.x,它支持通过 spring.cloud.config.server.searchNames 环境属性定义额外的文件名,就像一个单一的 springboot 一样应用程序,如文档的 Externalized Configuration.Application Property Files 部分中所定义,使用 spring.config.name 环境属性。我希望他们尽快对其进行审查,因为似乎很多人都在堆栈溢出中询问过此功能,并且肯定会有更多人搜索它并阅读当前建议的解决方案。

      值得一提的是,许多人建议“滥用”配置文件功能来实现这一点,在我看来,这是一种不好的做法,正如我在 this answer 中所描述的那样

      【讨论】:

        猜你喜欢
        • 2015-03-09
        • 2020-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-30
        • 2021-03-22
        • 2017-02-10
        相关资源
        最近更新 更多