Apollo(阿波罗)是携程开源的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,支持配置热发布并实时推送到应用端,并且具备规范的权限及流程治理等特性,适用于分布式微服务配置管理场景
Apollo配置中心介绍
程序功能日益复杂,程序配置日益增多:各种功能开关、参数配置、服务器地址...对程序配置的期望也越来越高:热部署并实时生效、灰度发布、分环境分集群管理配置、完善的权限审核机制...在这样的背景下,Apollo配置中心应运而生。Apollo支持四个维度Key-Value格式的配置* Application(应用) 实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置。每个应用都有对应的身份标识--appId,需要在代码中配置
- Environment(环境) 配置对应的环境,Apollo客户端需要知道当前应用出于哪个环境,,从而可以去获取应用的配置;环境和代码无关,同一份代码部署在不同的环境就应该获取不同环境的配置;环境默认是通过读取机器上的配置(server.properties的env属性)指定的
- Cluster(集群) 一个应用下不同实例的分组,例如按照不同数据中心划分,把上海机房的实例分为一个集群、把深圳机房的实例分为一个集群;对于不同的Cluster,同一个配置可以有不一样的值;集群默认是通过读取机器上的配置指定的(server.properties的idc属性)
- Namespace(命名空间) 一个应用下不同配置的分组,是配置项的集合,可以简单地把Namespace类别为(配置)文件,不同类型的配置存放在不同的文件中,例如数据库配置文件、RPC配置文件、应用自身的配置文件等;应用可以直接读取到公共组件的配置namespace,例如DAL、RPC等;应用也可以通过继承公共组件的配置namespace来对公共组件的配置做调整,如DAL的初始数据库连接数
Apollo在创建项目的时候,都会默认创建一个"application"的Namespace,"application"是个应用自身使用的。例如Spring Boot中项目的默认配置文件application.yaml,这里application.yaml就等同于"application"的Namespace。对于大多数应用来说,"application"Namespace已经能满足日常配置使用场景
客户端获取"application"Namespace的代码如下
Config config = ConfigService.getAppConfig()
客户端获取非"application"Namespace的代码如下
Config config = ConfigService.getConfig(namespaceName)
Namespace的格式 配置文件有多种格式,properties、xml、yml、yaml、json等,同样Namespace也具有这些格式tips: 非properties格式的namespace,在客户端使用时需要调用ConfigService.getConfigFile(String namespace, ConfigFileFormat configFileFormat)
来获取,如果使用Htpp接口直接调用时,对应的namespace参数需要传入namespace的名字加上后缀名,如datasource.jsonNamespace的获取权限分类 此处权限相是对于Apollo客户端来说的private(私有的)权限 private权限的Namespace,只能被所属的应用获取到。一个应用尝试获取其他应用private的Namespace,Apollo客户端会报"404"异常
public(公共的)权限 具有public权限的Namespace,能被任何应用获取
Namespace的类型
- 私有类型 具有private权限,例如上文中提到的"application"Namespace就是私有类型
- 公共类型 具有public权限,公共类型的Namespace相当于游离于应用之外的配置,且通过Namespace的名称去标识公共Namespace,所以公共Namespace的名称必须全局唯一
使用场景 部门级别共享的配置、小组级别共享的配置、几个项目之间共享的配置、中间件客户端的配置
- 关联类型(继承类型) 具有private权限,关联类型的Namespace继承于公共类型的Namespace,用于覆盖公共Namespace的某些配置。例如公共Namespace有两个配置项
k1 = v1
k2 = v2
然后应用A有一个关联类型的Namespace关联此公共Namespace,且以新值v3覆盖配置项k1。那么在应用A实际运行时,获取到的公共Namespace的配置为
k1 = v3
k2 = v2
使用场景 假设RPC框架的配置(如:timeout)有以下要求
* 提供一份全公司默认的配置,且可动态调整
* RPC客户端项目可以自定义某些配置项且可动态调整
结合Apollo的公共类型的Namespace和关联类型的Namespace。RPC团队在Apollo上维护一个叫“rpc-client”的公共Namespace,在"rpc-client"Namespace上配置默认的参数值。rpc-client.jar里的代码读取"rpc-client"Namespace的配置即可;如需要调整默认的配置,只需要修改公共类型"rpc-client"Namespace的配置;如果客户端项目想要自定义或动态修改某些配置项,只需要在Apollo自己项目下关联"rpc-client",就能创建关联类型"rpc-client"的Namespace,然后在关联类型下修改配置项即可。这里rpc-client.jar是在应用容器里运行的,所以rpc-client获取到"rpc-client"Namespace的配置是应用的关联类型的Namespace加上公共类型的Namespace
例子 如下图,有三个应用:应用A、应用B、应用C
应用A有两个私有类型的Namespace:application和NS-Private,以及一个关联类型的Namespace:NS-Public
应用B有一个私有类型的Namespace:application,以及一个公共类型的Namespace:NS-Public
应用C只有一个私有类型的Namespace:application
![](https://img-blog.csdnimg.cn/20190929223513136.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N1eTFfXw==,size_16,color_FFFFFF,t_70)
应用A获取Apollo配置
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v11
appConfig.getProperty("k2", null); // k2 = v21
//NS-Private
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", null); // k1 = v3
privateConfig.getProperty("k3", null); // k3 = v4
//NS-Public,覆盖公共类型配置的情况,k4被覆盖
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v6 cover
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7
应用B获取Apollo配置
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v12
appConfig.getProperty("k2",