前文
spring-boot:2.1.12
apollo-client: 1.6.0

一、实现本地配置覆盖远程配置实现

  1. Apollo客户端支持本地开发模式,这个主要用于当开发环境无法连接Apollo服务器的时候,这种方式主要用于无网情况下。
    在本地开发模式下,Apollo只会从本地文件读取配置信息,不会从Apollo服务器读取配置。
  2. 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。我这边创建的私有的配置,私有的配置,只会创建在该应用,公共的会在所有应用中。

apollo导出namespace apollo默认从本地获取配置_java


apollo导出namespace apollo默认从本地获取配置_java_02


apollo导出namespace apollo默认从本地获取配置_java_03

2、应用中引用该公共namespace并确保排序位于其它namespace之前,由于该namespace没有任何配置,所以对应用不会有任何影响。这里我建的是local,所以把local放第一位。

apollo.bootstrap.namespaces = local,application

3、在代码中resources下放一个META-INF/config/local.properties文件,在里面写入要覆盖的配置即可

apollo导出namespace apollo默认从本地获取配置_apollo导出namespace_04


配置文件使用本地配置参数。

这样就大功告成了,实现本地配置“覆盖”远程配置。

二、实现的原因

在Apollo中有预埋逻辑,会去尝试读取该文件作为namespace配置的补充。

DefaultConfig.java

apollo导出namespace apollo默认从本地获取配置_apollo导出namespace_05


apollo导出namespace apollo默认从本地获取配置_java_06


这种方式是本人最喜欢的方式了。想复用环境的大部分的一些配置,部分配置使用本地的。而不是重新弄一份完整的本地配置。