700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > SpringCloud配置中心-Config

SpringCloud配置中心-Config

时间:2019-11-12 10:04:50

相关推荐

SpringCloud配置中心-Config

本文主要讨论原理,不涉及使用示例。

一搭建Config Server

SpringCloud Config支持通过git、svn等搭建配置中心。因为目前使用git管理代码比较常见,所以接下来介绍通过git搭建配置中心。

1配置示例

以下git相关的是一些常用的配置:

spring.cloud.config.server.git.uri= Git仓库地址

spring.cloud.config.server.git.searchPaths=仓库中配置文件所在路径

spring.cloud.config.server.git.username= Git账号

spring.cloud.config.server.git.password= Git密码

配置后,可以通过一下url模式访问指定的配置文件的内容,例如:

http://localhost:7001/{application}/{profile}[/{label}]


http://localhost:7001/{application}-{profile}.yml


http://localhost:7001/{label}/{application}-{profile}.yml

http://localhost:7001/{application}-{profile}.properties


http://localhost:7001/{label}/{application}-{profile}.properties


2整体结构

远程git仓库:用来存储配置文件的地方,多环境配置文件使用{application}-{profile}.yml、{application}-{profile}.propreties

本地git仓库:缓存从远程git仓库中获取的配置信息,即便是远程git不能用,也可以从本地仓库中加载配置内容。

Config Server:分布式配置中心,指定了git仓库uri、搜索路径、访问账号和密码等。

微服务应用:配置客户端(Config Client),指定应用名、配置中心url、环境名、分支名等。

3启动流程

微服务应用启动,根据微服务系统中配置的应用名(application)、环境名(profile)、分支名(label),向Config Server请求配置信息。

Config Server根据配置的Git(或SVN)仓库信息加上客户端传来的配置定位信息去查配置信息的路径。

Config Server执行git clone命令,将配置信息下载到本地Git仓库中,将配置信息加载到Spring的ApplicationContext读取内容返回给客户端(微服务应用)

客户端将内容加载到ApplicationContext,配置内容的优先级大于客户端内部的配置内容,进行忽略

注意:Config Server从Git上拉取配置项以后,会缓存在本地。

4源码分析

1) EnvironmentRepository

在前面「整体结构」部分中,我们看到ConfigServer从仓库中获取配置信息,然后给到其他微服务,这里ConfigServer与仓库的操作都是通过EnvironmentRepository来实现的。EnvironmentRepository有一下几种:

参考EnvironmentRepositoryConfiguration类中的代码,如下所示:

@Configuration

@Profile("native")

protected static class NativeRepositoryConfiguration {

//代码略去

@Bean

public EnvironmentRepository environmentRepository() {

return new NativeEnvironmentRepository(this.environment);

}

}

@Configuration

@ConditionalOnMissingBean(EnvironmentRepository.class)

protected static class GitRepositoryConfiguration {

//代码略去

@Bean

public EnvironmentRepository environmentRepository() {

MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(this.environment);

if (this.server.getDefaultLabel()!=null) {

repository.setDefaultLabel(this.server.getDefaultLabel());

}

return repository;

}

}

@Configuration

@Profile("subversion")

protected static class SvnRepositoryConfiguration {

//代码略去

@Bean

public EnvironmentRepository environmentRepository() {

SvnKitEnvironmentRepository repository = new SvnKitEnvironmentRepository(this.environment);

if (this.server.getDefaultLabel()!=null) {

repository.setDefaultLabel(this.server.getDefaultLabel());

}

return repository;

}

}

上面的所有类都实现了EnvironmentRepository接口,这个接口之定义了一个方法,用来从Repository中查找需要的数据项。

public interface EnvironmentRepository {

Environment findOne(String application, String profile, String label);

}

2) 以git为例,简单介绍仓库代码管理过程

服务器启动时,属性设置完以后就会根据cloneOnStart的值决定是否从远程git仓库clone代码,如下JGitEnvironmentRepository#afterPropertiesSet方法所示:

public void afterPropertiesSet() throws Exception {

Assert.state(getUri() != null,

"You need to configure a uri for the git repository");

if (this.cloneOnStart) {

initClonedRepository();

}

}

/**

* Clones the remote repository and then opens a connection to it.

* @throws GitAPIException

* @throws IOException

*/

private void initClonedRepository() throws GitAPIException, IOException {

if (!getUri().startsWith(FILE_URI_PREFIX)) {

deleteBaseDirIfExists();

Git git = cloneToBasedir();

if (git != null) {

git.close();

}

git = openGitRepository();

if (git != null) {

git.close();

}

}

}

从源码中我们看到,首先会将配置从git上clone到本地,然后再进行其他的操作。接着就本地的git仓库中获取指定的数据了,见AbstractScmEnvironmentRepository#findOne代码,如下所示:

@Override

public synchronized Environment findOne(String application, String profile, String label) {

NativeEnvironmentRepository delegate = new NativeEnvironmentRepository(

getEnvironment());

Locations locations = getLocations(application, profile, label);

delegate.setSearchLocations(locations.getLocations());

Environment result = delegate.findOne(application, profile, "");

result.setVersion(locations.getVersion());

result.setLabel(label);

return this.cleaner.clean(result, getWorkingDirectory().toURI().toString(),

getUri());

}

注意代码中使用的是NativeEnvironmentRepository,这个是以本地的文件作为EnvironmentRepository的。

二搭建Client

1 配置说明

在大家server部分我们提到了application、profile、label,他们分别是通过一下配置项配置的。

spring.application.name:对应配置文件规则中的{application}部分

spring.cloud.config.profile:对应配置文件规则中的{profile}部分

spring.cloud.config.label:对应配置文件规则中的{label}部分

spring.cloud.config.uri:配置中心config-server的地址

示例如下:

spring.application.name=demo

spring.cloud.config.profile=dev

spring.cloud.config.label=master

那么可以通过以下url访问:http://localhost:7001/demo/dev

2源码分析

ConfigClientProperties#override方法中,我们可以看到通过客户端配置的spring.application.name、spring.cloud.config.profile、spring.cloud.config.label、spring.cloud.config.uri来生成ConfigClientProperties对象,而ConfigClientProperties中包含了要获取那个应用、分支、环境的配置信息。如下所示:

public static final String ConfigClientProperties

.PREFIX = "spring.cloud.config"

public ConfigClientProperties override(

org.springframework.core.env.Environment environment) {

ConfigClientProperties override = new ConfigClientProperties();

BeanUtils.copyProperties(this, override);

override.setName(environment.resolvePlaceholders("${" + ConfigClientProperties.PREFIX + ".name:${spring.application.name:application}}"));

if (environment.containsProperty(ConfigClientProperties.PREFIX + ".profile")) {

override.setProfile(environment.getProperty(ConfigClientProperties.PREFIX + ".profile"));

}

if (environment.containsProperty(ConfigClientProperties.PREFIX + ".label")) {

override.setLabel(

environment.getProperty(ConfigClientProperties.PREFIX + ".label"));

}

return override;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。