首页 >> 科技 >>列表

Spring Cloud Config 流程源码详解(原创)

网络整理 2020-01-12 20:29:49 作者:哀而不伤

核心接口是EnvironmentRepository,提供配置的读取

public interface EnvironmentRepository { Environment findOne(String application, String profile, String label); }

EnvironmentRepository有多种实现,基于JDBC、SVN、GIT等等

默认情况下,使用的是 MultipleJGitEnvironmentRepository(可以配置多个地址的GIT数据源)

ConfigServerAutoConfiguration -> EnvironmentRepositoryConfiguration -> DefaultRepositoryConfiguration

@Configuration @ConditionalOnMissingBean(value = EnvironmentRepository.class) class DefaultRepositoryConfiguration { ... @Bean public MultipleJGitEnvironmentRepository defaultEnvironmentRepository(...) throws Exception { return gitEnvironmentRepositoryFactory.build(environmentProperties); } }

MultipleJGitEnvironmentRepository 代理遍历每个 JGitEnvironmentRepository, JGitEnvironmentRepository 下使用 NativeEnvironmentRepository 代理读取本地文件。

AbstractScmEnvironmentRepository#findOne

public synchronized Environment findOne(String application, String profile, String label) { NativeEnvironmentRepository delegate = new NativeEnvironmentRepository(getEnvironment(), new NativeEnvironmentProperties()); Locations locations = getLocations(application, profile, label); delegate.setSearchLocations(locations.getLocations()); Environment result = delegate.findOne(application, profile, ""); ... getUri()); }

其中getLocations这部会从GIT远程仓库同步到本地

JGitEnvironmentRepository#getLocations -> JGitEnvironmentRepository.refresh

public String refresh(String label) { Git git = createGitClient(); ... checkout(git, label); ... merge(git, label); ... resetHard(...) ...}

配置文件加载优先级顺序(上面的覆盖下面的)

模式应用
{spring.application.name}-{profile}.properties/yml   应用-环境-配置  
{spring.application.name}.properties/yml   应用-全局-配置  
application-{profile}.properties/yml   公众-环境-配置  
application.properties/yml   公众-全局-配置  

具体的逻辑参考NativeEnvironmentRepository和ConfigFileApplicationListener

如何注入

ConfigServer本身也可以注入自己的读取的配置,使得其他服务可以和ConfigServer配置在一起,比如Eureka

Config的自身注入在BootStrap阶段

ConfigServerBootstrapConfiguration#LocalPropertySourceLocatorConfiguration

@Configuration @ConditionalOnProperty("spring.cloud.config.server.bootstrap") public class ConfigServerBootstrapConfiguration { @Bean public EnvironmentRepositoryPropertySourceLocator environmentRepositoryPropertySourceLocator() { return new EnvironmentRepositoryPropertySourceLocator(this.repository, this.client.getName(), this.client.getProfile(), getDefaultLabel()); } }

EnvironmentRepositoryPropertySourceLocator会调用EnvironmentRepository获取配置

public class EnvironmentRepositoryPropertySourceLocator implements PropertySourceLocator{ @Override public PropertySource<?> locate(Environment environment) { CompositePropertySource composite = new CompositePropertySource("configService"); for (PropertySource source : environmentRepository.findOne(name, profiles, label) .getPropertySources()) { composite.addPropertySource(...); } return composite; }}

PropertySourceBootstrapConfiguration#init负责所有BootStrap配置的加载,所有实现PropertySourceLocator接口的服务都会被调用

CompositePropertySource composite = new CompositePropertySource( BOOTSTRAP_PROPERTY_SOURCE_NAME); for (PropertySourceLocator locator : this.propertySourceLocators) { PropertySource<?> source = locator.locate(environment); composite.addPropertySource(source); }

Client

2种高可用方式, Spring-Cloud-Config-Client配置存在两种策略

通过ConfigServer获取注册中心地址和其他配置

通过注册中心获取ConfigServer地址,然后获得其他配置

参考国内比较成熟的分布式集中配置,比如百度Disconf,携程Apollo等基本都是第1种策略,好处是唯一需要本地写死的是配置中心的参数.

但是Spring Cloud 1.X 并不支持ConfigServer集群的高可用配置。需要单独将spring-cloud-starter-config升级到2.x(可以和其他1.x组件混用)

升级后就可以配多个地址了,如下:

spring: application: name: user cloud: config: fail-fast: true profile: dev label: master uri: :8761/config, :8762/config, :8763/config

但是网上更多介绍的是第二种方案,这里也贴出来。配置项更多了,需要同时指定configserver和eureka

spring: application: name: user cloud: config: fail-fast: true profile: dev label: master discovery: enabled: true serviceId: dashboard eureka: client: register-with-eureka: true fetch-registry: true serviceUrl: defaultZone: :8761/eureka/,:8762/eureka,:8763/eureka

启动过程和ConfigServer注入过程类似

上海联通信息港 - 为网友提供互联网每日热点内容
上海联通信息港是一个自媒体内容聚合分享平台,为网友提供互联网每日新闻和热点内容分享,今日看点新闻头条增长知识!