这是我参与更文挑战的第 11 天,活动详情查看: 更文挑战
《配置中心 Spring Cloud Config 详解》系列文章更新,一起在技术的路上精进!本系列文章将会介绍Spring Cloud 中提供了分布式配置中心Spring Cloud Config。应用服务中除了实现系统功能的代码,还需要连接资源和其它应用,经常有很多需要在外部配置的数据去调整应用的行为,如切换不同的数据库,设置功能开关等。随着微服务的不断增加,需要系统具备可伸缩和可扩展性,除此之外就是管理相当多的服务实例的配置数据。在应用的开发阶段由各个服务自治,但是到了生产环境之后会给运维带来很大的麻烦,特别是微服务的规模比较大,配置的更新更为麻烦。为此,系统需要建立一个统一的配置管理中心。
在前面的文章,我们进一步介绍了如何获取指定服务的资源文件。本文将会介绍 Spring Cloud Config 服务端内置了一些对外查询的 API 端点。
Config Server提供的端点
ConfigServerMvcConfiguration
对 Controller 的端点进行配置。配置服务器对外提供的 API 端点包括三类:Environment、Resource 以及加密解密的端点。我们将会介绍前两类常用的 API 端点。
@Configuration
@ConditionalOnWebApplication
public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter {
@Bean
public EnvironmentController environmentController(EnvironmentRepository envRepository, ConfigServerProperties server) {
EnvironmentController controller = new EnvironmentController(encrypted(envRepository, server), this.objectMapper);
controller.setStripDocumentFromYaml(server.isStripDocumentFromYaml());
return controller;
}
...
private EnvironmentRepository encrypted(EnvironmentRepository envRepository, ConfigServerProperties server) {
EnvironmentEncryptorEnvironmentRepository encrypted = new EnvironmentEncryptorEnvironmentRepository(
envRepository, this.environmentEncryptor);
encrypted.setOverrides(server.getOverrides());
return encrypted;
}
}
复制代码
配置文件ConfigServerMvcConfiguration
将EnvironmentController
加入了Spring的上下文中,并自动注入EnvironmentRepository
和ConfigServerProperties
对象。
在将配置信息返回给客户端服务之前,远端加密的属性值将会被解密(以{cipher}开头的字符串)。这里的#encrypted
方法,就是将给定的EnvironmentRepository
再次封装,返回一个代理类用以解密属性。Overrides
属性,即为在配置服务器设置的属性,用以强制覆写客户端对应的环境变量,这里一起封装到代理类。stripDocumentFromYaml
属性用来标识不是 map 的 YAML 文档应该去掉Spring增加的文档的前缀,默认为 true。
获取Environment的端点
Environment 控制器提供了如下的端点:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
如上的格式都可以获取指定应用的配置环境信息。如URI为 /config-client/dev、/config-client-dev.yml 等。
配置仓库采用 Git 的方式,获取指定应用的 Environment 过程如下:
通过请求的时序图,可以清楚地知道客户端每次拉取的配置都是本地仓库复制的那一份,通过NativeEnvironmentRepository
代理获取指定应用的配置;Config Server每次都会检查指定Git仓库的状态,当远端仓库有更新时,则会fetch到本地进行更新。
public class EnvironmentController {
//根据参数应用名和profile,返回Environment对象
@RequestMapping("/{name}/{profiles:.*[^-].*}")
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
return labelled(name, profiles, null);
}
@RequestMapping("/{label}/{name}-{profiles}.properties")
public ResponseEntity<String> labelledProperties(@PathVariable String name,
@PathVariable String profiles, @PathVariable String label,
@RequestParam(defaultValue = "true") boolean resolvePlaceholders)
throws IOException {
validateProfiles(profiles);
Environment environment = labelled(name, profiles, label);
Map<String, Object> properties = convertToProperties(environment);
String propertiesString = getPropertiesString(properties);
if (resolvePlaceholders) {
propertiesString = resolvePlaceholders(prepareEnvironment(environment),
propertiesString);
}
return getSuccess(propertiesString);
}
//...
}
复制代码
控制器调用相应环境仓库实现的#findOne
方法。既可以返回完整的 Environment 对象,包括name、profiles、propertySources 这些信息,也可以直接返回配置仓库中的源配置数据,还可以直接返回处理之后的 json 对象。/{label}/{name}-{profiles}.properties
这个接口对应的实现中,首先调用#labelled
方法返回 Environment 对象,然后将对象转换成 map,由 map 转成 string,最后替换掉系统的环境变量的占位符,返回文本对象。
小结
本文主要介绍了 Spring Cloud Config 服务端内置了一些对外查询的 API 端点及其实现,我们可以通过这些 REST 接口快速地实现拉取配置信息。