问题描述

     基于 spring-cloud微服务开发,通常会配置一个Spring-Cloud-Config-Server,各个客户端会通过Spring-Cloud-Config-Server从配置仓库拉取自己服务的配置,如何配置Spring-Cloud-Config-Server,可以参考本人前段时间写的文章“Spring-cloud Config Server 3种配置方式

    假如客户端Service-A 对应的配置文件为ServiceA.properties,假如客户端Service-B对应的配置文件为ServiceB.properties,如果两个服务都需要使用同一个服务发现(Eureka)的配置,岂不是要在ServiceA.propertiesServiceB.properties中配置两遍,这样的话,万一以后服务发现(Eureka)的配置改了,就要每个服务的配置文件都要去修改了,这样非常难以维护。所以想到了利用公共文件方法,现在在这里简单阐述一下如何配置。(下面例子Spring-Cloud-Config-Server都是使用本地配置方式)。

 

方法一:

    在配置仓库的根目录创建一个子目录,(注:子目录最好不要用config作为目录名称,为什么,看下文),然后创建application.properties作为公共文件。ServiceA-dev.properties、ServiceB-dev.properties作为各个客户端服务的单独配置文件。

客户端ServiceA-dev.properties的配置:

spring.application.name=ServiceA
spring.cloud.config.uri=http://localhost:8762/config-server
spring.cloud.config.failFast=true
spring.cloud.config.profile=dev

客户端ServiceB-dev.properties的配置:

spring.application.name=ServiceB
spring.cloud.config.uri=http://localhost:8762/config-server
spring.cloud.config.failFast=true
spring.cloud.config.profile=dev

启动信息如下:

INFO 8754 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='classpath:/config1/ServiceA-dev.properties'], MapPropertySource [name='classpath:/config1/application.properties']]]

可以在日志上看到读取了两个配置文件信息了。

    客户端在启动的时候,如果在单独配置文件中,找不到配置项,就会到公共配置文件中获取。单独配置文件配置项的优先级大于公共公共配置文件的配置项。这里说明一下为什么子目录最好不要用config作为目录名称,因为如果用了config作为字幕了名称,这样Spring-Cloud-Config-Server在启动的时候,就会优先读取config子目录下的application.properties。原因是Spring Boot 提供的 SpringApplication 类会搜索并加载 application.properties 文件来获取配置属性值。SpringApplication 类会在下面位置搜索该文件。(优先级从上到下)

  • 当前目录的“/config”子目录。
  • 当前目录。
  • classpath 中的“/config”包。
  • classpath

 通常Spring-Cloud-Config-Server的配置都是单独配置的,不要跟客户端使用同一些配置项,所以这就是为什么子目录最好不要用config作为目录名称的原因。

方法二:

如果你非得要用config作为子目录的目录名称,那你的公共文件就不要用application作为公共文件的名称咯,如何进行公共文件配置呢,开始搜索了好多文章,有一个文章是这样配置的:

例如:

service-a 客户端的 bootstap.yml

spring:
  application:
    name: service-a, datasorce

service-b 客户端的 bootstap.yml

spring:
  application:
    name: service-b, datasorce

但是启动客户端项目的时候,压根就会报错:错误信息如下

    Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String  
        at com.netflix.config.ConfigurationBasedDeploymentContext.getValueFromConfig(ConfigurationBasedDeploymentContext.java:329) ~[archaius-core-0.7.4.jar:0.7.4]  
        at com.netflix.config.ConfigurationBasedDeploymentContext.getValue(ConfigurationBasedDeploymentContext.java:349) ~[archaius-core-0.7.4.jar:0.7.4]  

后来怎么去解决都行不通的,其实想想就知道用spring.application.name来配置多个配置文件名,这样的话,服务发现(eureka)是利用spring.application.name作为application Name的,这样设置一个客户端服务有两个服务名,肯定是不恰单的。

如何去配置才可以呢?其实可以在spring.cloud.config.name这里去配置多个配置文件名,这里的common.properties就是公共配置文件。

spring.application.name=ServiceA
spring.cloud.config.uri=http://localhost:8762/config-server
spring.cloud.config.name=ServiceA,common
spring.cloud.config.failFast=true
spring.cloud.config.profile=dev

这样启动的时候可以在日志上看到读取了两个配置文件信息了

 INFO 8736 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='classpath:/config/ServiceA-dev.properties'], MapPropertySource [name='classpath:/config/common.properties']]]

参考资料:

Sharing Configuration With All Applications

稿毕!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐