前言
Config 服务端默认的存储实现是 Git ,这能够很容易地支持配置环境的标签版本,而且有各种工具方便地管理这些配置内容,包括统一配置实时推送,不同环境隔离管理等特点。
一、基础使用
1、server端
1.1、增加pom配置
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
1.2、入口类添加@EnableConfigServer 注解
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ConfigServerApplication.class).web(WebApplicationType.SERVLET).run(args);
}
1.3、配置信息:
// 服务名称
spring.application.name = config-server-eureka
// 服务的端口号
server.port = 60001
// 与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址
eureka.client.serviceUrl.defaultZone = http://localhost:20000/eureka/
// Git仓库的地址
spring.cloud.config.server.git.uri =
// Git仓库地址下的相对地址,使用“,”分割
spring.cloud.config.server.git.search-paths =
// Git仓库的账号
spring.cloud.config.server.git.username =
// Git仓库的密码
spring.cloud.config.server.git.password =
2、client端
2.1、增加pom配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2.2、配置文件:
// Git上配置文件的名称
spring.cloud.config.name = config-name
// 获取配置的策略 建议由外部注入
spring.cloud.config.profile = prod
// 获取配置文件的分支,默认是master。如果是是本地获取的话,则无用
spring.cloud.config.label = master
// 开启配置信息发现
spring.cloud.config.discovery.enabled = true
// 配置中心的service-id,便于扩展为高可用配置集群
spring.cloud.config.discovery.serviceId = config-server-eureka
// 与Eureka Server交互的地址,客户端的查询服务和注册服务使用
eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka/
2.3、入口类代码:
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class, args);
System.out.println("配置中心客户端启动成功!");
}
}
二、源码解析
Config Server加载资源文件
1.1、从启动类的@EnableConfigServer
注解进入
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ConfigServerConfiguration.class)
public @interface EnableConfigServer {
}
1.2、其中Import了ConfigServerConfiguration
类
@Configuration
public class ConfigServerConfiguration {
@Bean
public Marker enableConfigServerMarker() {
return new Marker();
}
class Marker {
}
}
1.3、通过Marker了解到,开启了ConfigServerConfiguration
类:
当启用了 Config Server之后,配置服务器在启动时就需要对 Config Server 进行自动配置,在 ConfigServerAutoConfiguration类中引入了多个配置类:
EnvironmentRepositoryConfiguration:环境变量存储相关的配置
CompositeConfiguration:组合方式的环境仓储配置
ResourceRepositoryConfiguration:资源仓储相关的配置
ConfigServerEncryptionConfiguration:加密端点的配置
ConfigServerMvcConfiguration:对外暴露的 MVC 端点控制器的配置
@Configuration
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class,
ResourceRepositoryConfiguration.class, ConfigServerEncryptionConfiguration.class,
ConfigServerMvcConfiguration.class })
public class ConfigServerAutoConfiguration {
}
1.4、EnvironmentRepositoryConfiguration
类是配置中心的关键Configuration类
EnvironmentRepositoryConfiguration
通过profile注解(对当前应用的环境)决定使用装配哪个EnvironmentRepository Bean
EnvironmentRepository
是一个配置管理仓库接口,抽象了获取配置的方法
1.5、进入到重要的EnvironmentController
,就是对外提供接口的类
1.6、name就是对应的服务名,profiles对应的是环境名,label对应的是分支名
@RequestMapping("/{name}/{profiles}/{label:.*}")
public Environment labelled(@PathVariable String name, @PathVariable String profiles,@PathVariable String label) {
if (name != null && name.contains("(_)")) {
// "(_)" is uncommon in a git repo name, but "/" cannot be matched
// by Spring MVC
name = name.replace("(_)", "/");
}
if (label != null && label.contains("(_)")) {
// "(_)" is uncommon in a git branch name, but "/" cannot be matched
// by Spring MVC
label = label.replace("(_)", "/");
}
Environment environment = this.repository.findOne(name, profiles, label);
if (!this.acceptEmpty
&& (environment == null || environment.getPropertySources().isEmpty())) {
throw new EnvironmentNotFoundException("Profile Not found");
}
return environment;
}
1.7、 进入defaultLabel方法,它会再调用labelled方法,在labelled方法中,会调用repository的findOne()
来加载配置,然后返回给配置获取方
@RequestMapping("/{name}/{profiles:.*[^-].*}")
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
return labelled(name, profiles, null);
}
@RequestMapping("/{name}/{profiles}/{label:.*}")
public Environment labelled(@PathVariable String name, @PathVariable String profiles,
@PathVariable String label) {
if (label != null && label.contains("(_)")) {
// "(_)" is uncommon in a git branch name, but "/" cannot be matched
// by Spring MVC
label = label.replace("(_)", "/");
}
Environment environment = this.repository.findOne(name, profiles, label);
return environment;
}
EnvironmentEncryptorEnvironmentRepository
类中的findOne()
方法:
public class EnvironmentEncryptorEnvironmentRepository implements EnvironmentRepository {
private EnvironmentRepository delegate;
private EnvironmentEncryptor environmentEncryptor;
private Map<String, String> overrides = new LinkedHashMap<>();
public EnvironmentEncryptorEnvironmentRepository(EnvironmentRepository delegate) {
this(delegate, null);
}
public EnvironmentEncryptorEnvironmentRepository(EnvironmentRepository delegate,
EnvironmentEncryptor environmentEncryptor) {
this.delegate = delegate;
this.environmentEncryptor = environmentEncryptor;
}
@Override
public Environment findOne(String name, String profiles, String label) {
// 代理模式
Environment environment = this.delegate.findOne(name, profiles, label);
if (this.environmentEncryptor != null) {
environment = this.environmentEncryptor.decrypt(environment);
}
if (!this.overrides.isEmpty()) {
environment.addFirst(new PropertySource("overrides", this.overrides));
}
return environment;
}
/**
* @param overrides the overrides to set
*/
public void setOverrides(Map<String, String> overrides) {
this.overrides = new HashMap<>(overrides);
for (String key : overrides.keySet()) {
if (overrides.get(key).contains("\\{")) {
this.overrides.put(key, overrides.get(key).replace("\\{", "{"));
}
if (overrides.get(key).contains("\\${")) {
this.overrides.put(key, overrides.get(key).replace("\\${", "${"));
}
}
}
}
使用git命令,在本地存了一份文件,直接先删除之前保存的,更新保存新的配置文件
c对应的git命令
从git上拉取的配置文件在本地的保存地址