Spring-Cloud-Config 多服务公共文件配置
问题描述 基于 spring-cloud微服务开发,通常会配置一个Spring-Cloud-Config-Server,各个客户端会通过Spring-Cloud-Config-Server从配置仓库拉取自己服务的配置,如何配置Spring-Cloud-Config-Server,可以参考本人前段时间写的文章“Spring-cloud Config Server 3种配置方式”。 ...
问题描述
基于 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.properties和ServiceB.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
稿毕!
更多推荐
所有评论(0)