Apollo分布式配置中心专题1-基础和使用

1. 概览

1.1 什么是配置

随着程序功能的日益复杂,程序的配置日益增多:各种功能的==开关==、==参数==的配置、服务器的地址等

对程序配置的期望值也越来越高:配置修改后==实时生效==,==灰度发布==,分环境、分集群管理配置,完善的==权限==、==审核机制==等

在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。

配置主要有以下几个属性:

  • 配置是独立于程序的只读变量

    • 配置首先是独立于程序的,同一份程序在不同的配置下会有不同的行为。
    • 配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置。
  • 配置伴随应用的整个生命周期

    • 配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。
  • 配置可以有多种加载方式

    • 配置也有很多种加载方式,常见的有程序内部hard code,配置文件,环境变量,启动参数,基于数据库,redis等
  • 配置需要治理

    • 权限控制
      • 由于配置能改变程序的行为,不正确的配置甚至能引起灾难,所以对配置的修改必须有比较完善的权限控制
    • 不同环境、集群配置管理
      • 同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理

1.2 什么是配置中心

1.2.1 单机

Apollo分布式配置中心专题1-基础和使用_第1张图片
image.png

1.2.2 多机

Apollo分布式配置中心专题1-基础和使用_第2张图片
image.png

1.2.3 微服务化

Apollo分布式配置中心专题1-基础和使用_第3张图片
image.png

1.2.4 配置中心

配置中心将配置从应用中剥离出来,统一管理,优雅的解决了配置的动态变更、持久化、运维成本等问题。
应用自身既不需要去添加管理配置接口,也不需要自己去实现配置的持久化。

总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件

2. Apollo简介

2.1 主流配置中心

  1. Spring Cloud Config
  2. Nacos
  3. Disconf
  4. Apollo
  5. ...

2.1.1 功能性能对比

目前只用过Spring Cloud Config和Apollo。

说说Spring Cloud Config感受:

  1. 依赖git,无配置后台
  2. 不同环境不同服务都有properties文件
  3. 修改配置需要发布项目或者手动刷新

因此,当时开发时大家几乎不依赖配置中心。【手动滑稽】

2.2 Apollo简介

Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

服务端基于 Spring Boot 和 Spring Cloud 开发,打包后可以直接运行,不需要额外安装 Tomcat 等应用容器。

Java 客户端不依赖任何框架,能够运行于所有 Java 运行时环境,同时对 Spring/Spring Boot 环境也有额外支持。

2.3 Apollo特性

  • 统一管理不同环境、不同集群的配置

    • Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
    • 同一份代码部署在不同的集群,可以有不同的配置,比如zookeeper的地址等
    • 通过命名空间(namespace)可以很方便地支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
  • 配置修改实时生效(热发布)

    • 用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序
  • 版本发布管理

    • 所有的配置发布都有版本概念,从而可以方便地支持配置的回滚
  • 灰度发布

    • 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例
  • 权限管理、发布审核、操作审计

    • 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
    • 所有的操作都有审计日志,可以方便地追踪问题
  • 客户端配置信息监控

    • 可以在界面上方便地看到配置在被哪些实例使用
  • 提供Java和.Net原生客户端

    • 提供了Java和.Net的原生客户端,方便应用集成
    • 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
    • 同时提供了Http接口,非Java和.Net应用也可以方便地使用
  • 提供开放平台API

    • Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过Apollo出于通用性考虑,不会对配置的修改做过多限制,只要符合基本的格式就能保存,不会针对不同的配置值进行针对性的校验,如数据库用户名、密码,Redis服务地址等
    • 对于这类应用配置,Apollo支持应用方通过开放平台API在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
  • 部署简单

    • 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
    • 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
    • Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数

3. Apollo快速入门

3.1 执行流程

Apollo分布式配置中心专题1-基础和使用_第4张图片
image.png

过程:

  1. 用户在配置中心对配置进行修改并发布
  2. 配置中心通知Apollo客户端有配置更新
  3. Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用

3.2 Demo

QuickStart

http://106.54.227.205/signin

  • 账号:apollo
  • 密码:admin

3.3 日常使用Apollo的姿势

Config config = ConfigService.getAppConfig();
Integer defaultRequestTimeout = 200;
Integer requestTimeout = config.getIntProperty("requestTimeout", defaultRequestTimeout)

4 Apollo架构和核心概念

4.1 Apllo架构

Apollo分布式配置中心专题1-基础和使用_第5张图片
image.png

上图简要描述了 Apollo 的总体设计,从下往上看:

  1. Config Service 提供配置的读取、推送等功能,服务对象是Apollo客户端

  2. Admin Service 提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)

  3. 通过Apollo的发布界面可以多环境、集群管理配置。
    Config Service 和 Admin Service 都是多实例、无状态部署,所以需要将自己注册到
    Eureka 中并保持心跳,在 Eureka 之上架了一层 Meta Server 用于封装 Eureka 的服务发现接口。Apollo提供了MetaServiceProvider SPI,用户可以注入自己的MetaServiceProvider来自定义Meta Server定位逻辑

  4. Client 通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port 访问服务,同时在 Client 侧会做 load balance、错误重试

注:Meta Server从Eureka获取Config Service和Admin Service的服务信息,相当于是一个Eureka Client

4.2 Apollo核心概念

Apollo分布式配置中心专题1-基础和使用_第6张图片
image.png
  1. application (应用)

    • 这个很好理解,就是实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置
    • 每个应用都需要有唯一的身份标识 -- appId,我们认为应用身份是跟着代码走的,所以需要在代码中配置。
  2. environment (环境)

    • 配置对应的环境,Apollo客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置
    • 我们认为环境和代码无关,同一份代码部署在不同的环境就应该能够获取到不同环境的配置
    • 所以环境默认是通过读取机器上的配置(server.properties中的env属性)指定的,不过为了开发方便,我们也支持运行时通过System Property等指定。
  3. cluster (集群)

    • 一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。
    • 对不同的cluster,同一个配置可以有不一样的值,如zookeeper地址。
    • 集群默认是通过读取机器上的配置(server.properties中的idc属性)指定的,不过也支持运行时通过System Property指定。
  4. namespace (命名空间)

    • 一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等
    • 应用可以直接读取到公共组件的配置namespace,如DAL,RPC等
    • 应用也可以通过继承公共组件的配置namespace来对公共组件的配置做调整,如DAL的初始数据库连接数

4.3 Namespace设计

4.3.1 Namespace概念

Namespace是配置项的集合,类似于一个配置文件的概念。

Apollo在创建项目的时候,都会默认创建一个“application”的Namespace。

4.3.1 Namespace获取权限

Namespace的获取权限分为两种:

  • private(私有的)

    private权限的Namespace只能被所属的应用获取到。一个应用尝试获取其它应用private的Namespace,Apollo会报“404”异常。

  • public(公共的)。

    public权限的Namespace,能被任何应用获取到

4.3.2 Namespace类型

有三种

  • 私有类型

    私有类型的Namespace具有private权限。例如上文提到的“application” Namespace就是私有类型。

  • 公共类型

    公共类型的Namespace具有public权限。公共类型的Namespace相当于游离于应用之外的配置,且通过Namespace的名称去标识公共Namespace,所以公共的Namespace的名称必须全局唯一。

  • 关联类型(继承类型)

    关联类型又可称为继承类型,关联类型具有private权限。关联类型的Namespace继承于公共类型的Namespace,用于覆盖公共Namespace的某些配置。

4.3.4 例子

如下图所示,有三个应用:应用A、应用B、应用C。

  • 应用A有两个私有类型的Namespace:application和NS-Private,以及一个关联类型的Namespace:NS-Public。
  • 应用B有一个私有类型的Namespace:application,以及一个公共类型的Namespace:NS-Public。
  • 应用C只有一个私有类型的Namespace:application
Apollo分布式配置中心专题1-基础和使用_第7张图片
image.png

应用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", null); // k2 = null
  appConfig.getProperty("k3", null); // k3 = v32
  
  //NS-Private,由于没有NS-Private Namespace 所以获取到default value
  Config privateConfig = ConfigService.getConfig("NS-Private");
  privateConfig.getProperty("k1", "default value"); 
  
  //NS-Public
  Config publicConfig = ConfigService.getConfig("NS-Public");
  publicConfig.getProperty("k4", null); // k4 = v5
  publicConfig.getProperty("k6", null); // k6 = v6
  publicConfig.getProperty("k7", null); // k7 = v7

应用C获取Apollo配置

  //application
  Config appConfig = ConfigService.getAppConfig();
  appConfig.getProperty("k1", null); // k1 = v12
  appConfig.getProperty("k2", null); // k2 = null
  appConfig.getProperty("k3", null); // k3 = v33
  
  //NS-Private,由于没有NS-Private Namespace 所以获取到default value
  Config privateConfig = ConfigService.getConfig("NS-Private");
  privateConfig.getProperty("k1", "default value"); 
  
  //NS-Public,公共类型的Namespace,任何项目都可以获取到
  Config publicConfig = ConfigService.getConfig("NS-Public");
  publicConfig.getProperty("k4", null); // k4 = v5
  publicConfig.getProperty("k6", null); // k6 = v6
  publicConfig.getProperty("k7", null); // k7 = v7

5. Apollo使用

5.0 管理员工具

5.0.1 用户管理

Apollo分布式配置中心专题1-基础和使用_第8张图片
image.png

5.0.2 系统权限管理

Apollo分布式配置中心专题1-基础和使用_第9张图片
image.png

5.0.3 删除应用,集群,AppNamespace

Apollo分布式配置中心专题1-基础和使用_第10张图片
image.png

5.0.4 系统信息

Apollo分布式配置中心专题1-基础和使用_第11张图片
image.png

5.1 项目管理

5.1.1 查看项目

Apollo分布式配置中心专题1-基础和使用_第12张图片
image.png

5.1.2 创建项目

Apollo分布式配置中心专题1-基础和使用_第13张图片
image.png

输入项目信息

  • 部门:选择应用所在的部门
  • 应用AppId:用来标识应用身份的唯一id,格式为string,需要和项目配置文件applications.properties 中配置的app.id对应
  • 应用名称:应用名,仅用于界面展示
  • 应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等 权限

5.1.3 修改项目信息

Apollo分布式配置中心专题1-基础和使用_第14张图片
image.png

5.1.4 项目权限管理

Apollo分布式配置中心专题1-基础和使用_第15张图片
image.png

5.2 配置管理

5.2.1 添加发布配置项

  1. 通过表格模式添加配置


    Apollo分布式配置中心专题1-基础和使用_第16张图片
    image.png
Apollo分布式配置中心专题1-基础和使用_第17张图片
image.png
  1. 通过文本模式编辑
Apollo分布式配置中心专题1-基础和使用_第18张图片
image.png

5.2.2 发布配置项

Apollo分布式配置中心专题1-基础和使用_第19张图片
image.png

5.2.3 修改配置

Apollo分布式配置中心专题1-基础和使用_第20张图片
image.png

5.2.4 删除配置

Apollo分布式配置中心专题1-基础和使用_第21张图片
image.png

5.2.5 回滚配置

Apollo分布式配置中心专题1-基础和使用_第22张图片
image.png

5.2.6 变更和发布历史

Apollo分布式配置中心专题1-基础和使用_第23张图片
image.png

5.3 多项目配置

5.3.1 关联公共Namespace

5.4 集群管理

5.5 多环境管理

5.6 灰度发布

灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用 产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。

5.6.1 Apollo实现的功能

  1. 对于一些对程序有比较大影响的配置,可以先在一个或者多个实例生效,观察一段时间没问题后再全量发布 配置。
  2. 对于一些需要调优的配置参数,可以通过灰度发布功能来实现A/B测试。可以在不同的机器上应用不同的配 置,不断调整、测评一段时间后找出较优的配置再全量发布配置。

6. 踩坑实录(不完全统计)

6.1 未上线配置提前发布到线上

6.2 多集群发布时,没有全部发布。

生产环境的apollo配置,有3个集群:default、bd、bj2。假设有A、B、C三个配置参数,default集群配置了A、B、C三个参数,bd、bj2配置了C一个参数。当apollo配置发布后,bd集群的机器也会到apollo里去找A、B、C三个参数,即使A、B两个参数没有配置。

6.3 配置格式校验

qa环境进行校验,不要直接上线

8. 参考

  1. https://github.com/ctripcorp/apollo

  2. https://www.jianshu.com/p/edce8e8c139e

  3. https://www.bilibili.com/video/BV1eE41187sS?t=5

你可能感兴趣的:(Apollo分布式配置中心专题1-基础和使用)