前文
spring-boot:2.1.12
apollo-client: 1.6.0
一、实现本地配置覆盖远程配置实现
- Apollo客户端支持本地开发模式,这个主要用于当开发环境无法连接Apollo服务器的时候,这种方式主要用于无网情况下。
在本地开发模式下,Apollo只会从本地文件读取配置信息,不会从Apollo服务器读取配置。 - apollo从4个维度去管理配置,分别是application (应用)、environment (环境)、cluster (集群)、namespace (命名空间)。所以我们可以新建一个专属本地开发的environment 的配置。
这与我设想的要不一样,本地开发模式属于离网模式下的纯本地配置读取。又不想新建environment去管理一份完整的配置。而且开发配置本身就已经建立了一套。
后来无意中发现
Apollo除了支持API方式获取配置,也支持和Spring/Spring Boot集成,集成原理简述如下。
Spring从3.1版本开始增加了ConfigurableEnvironment和PropertySource:
- ConfigurableEnvironment
- Spring的ApplicationContext会包含一个Environment(实现ConfigurableEnvironment接口)
- ConfigurableEnvironment自身包含了很多个PropertySource
- PropertySource 属性源 可以理解为很多个Key - Value的属性配置
PropertySource之间是有优先级顺序的,如果有一个Key在多个property source中都存在,那么在前面的property source优先。
Apollo和Spring/Spring Boot集成的手段就呼之欲出了:在应用启动阶段,Apollo从远端获取配置,然后组装成PropertySource并插入到第一个即可。
于是有了下面这种实现方式:
1、在apollo创建一个公共namespace,比如local.properties,配置为空并发布
进入 Apollo Portal 界面,进入对应的应用,选择新增一个公共的namespace。我这边创建的私有的配置,私有的配置,只会创建在该应用,公共的会在所有应用中。
2、应用中引用该公共namespace并确保排序位于其它namespace之前,由于该namespace没有任何配置,所以对应用不会有任何影响。这里我建的是local,所以把local放第一位。
apollo.bootstrap.namespaces = local,application
3、在代码中resources下放一个META-INF/config/local.properties文件,在里面写入要覆盖的配置即可
配置文件使用本地配置参数。
这样就大功告成了,实现本地配置“覆盖”远程配置。
二、实现的原因
在Apollo中有预埋逻辑,会去尝试读取该文件作为namespace配置的补充。
DefaultConfig.java
这种方式是本人最喜欢的方式了。想复用环境的大部分的一些配置,部分配置使用本地的。而不是重新弄一份完整的本地配置。