# 概述

## 配置项

无论是在单机时代还是分布式的环境下，我们的系统中都会存在大量配置项，这些配置项可以分为以下几类：

* **静态配置**：所谓静态配置，就是在程序启动前一次性配好，启动时一次性生效，在程序运行期一般不会变化的配置。
  * `环境相关配置`：有些配置是和环境相关的，每个环境的配置不一样，例如数据库、中间件和其它服务的连接字符串配置。这些配置一次性配好，运行期一般不变。
  * `安全相关配置`：和安全相关，例如用户名，密码，访问令牌，许可证书等，这些配置也是一次性配好，运行期一般不变。因为涉及安全，相关信息一般需要加密存储，对配置访问需要权限控制。
* **动态配置**：所谓动态配置，就是在程序的运行期可以根据需要动态调整的配置。动态配置让应用行为和功能的调整变得更加灵活。
  * `应用配置`：和应用相关的配置，例如服务请求超时，线程池和队列的大小，缓存过期时间，数据库连接池的容量，日志输出级别，限流熔断阀值，服务安全黑白名单等。一般开发或者运维会根据应用的实际运行情况调整这些配置。
  * `业务配置`：和业务相关的一些配置，例如促销规则，贷款额度，利率等业务参数，A/B测试参数等。一般产品运营或开发人员会根据实际的业务需求，动态调整这些参数。
  * `功能开关`：在英文中也称Feature Flag/Toggle/Switch，简单的只有真假两个值，复杂的可以是多值参数。功能开关是DevOps的一种最佳实践，在运维中有很多应用场景，比如蓝绿部署，灰度开关，降级开关，主备切换开关，数据库迁移开关等。

如果我们对上述种种配置项进行归纳，可以发现它们都具有如下属性或特点：

* 配置项的值是一个有限空间（一个或多个）的值集合；
* 配置项的值往往跟具体的环境（开发/测试/预发/生产等）相关联，现实中相当一部分配置在不同的环境必须设定不同的值，但是也有相当的另一部分配置在不同的环境要设定为完全一致的值。
* 配置项的值不会非常频繁的需要进行调整；
* 配置项的值一旦需要变更，则需要快速传播：使用该配置的目标集群的所有节点要几乎同时收到变更，然后几乎整齐划一的统一调整行为。

## 为什么需要配置中心

面对如此众多复杂的配置项，要如何对其进行管理呢？传统程序中配置方式主要有以下几种：

* **程序内部硬编码**
* **使用配置文件**，比如最常见的`jdbc.properties`；
* **使用环境变量**：将配置预置在操作系统的环境变量里，程序运行时读取；
* **使用启动参数**：在程序启动时一次性提供参数；
* **基于数据库实现动态配置**：将配置放在数据库中，可以在运行期灵活调整配置；

但上述的这些传统的管理方式，会存在以下问题：

* **配置散乱格式不标准：**&#x6709;的用properties格式，有的用xml格式，还有的存DB，团队倾向自造轮子，做法五花八门；
* **采用本地静态配置，配置修改麻烦：**&#x914D;置修改一般需要经过一个较长的测试发布周期。在分布式微服务环境下，当服务实例很多时，修改配置费时费力；
* **易引发生产事故：**&#x6BD4;如将测试环境的配置带到生产上，引发事故；
* **缺乏安全审计：**&#x8C01;改的配置？改了什么？什么时候改的？无从追溯；
* **版本控制功能：**&#x65E0;法查看某个配置项的修改历史，一旦出现问题无法及时回滚；

而这些问题，都是需要配置中心去解决的。

## 配置管理的核心需求

近年，持续交付和DevOps理念开始逐步被一线企业接受，微服务架构和容器云也逐渐在一线企业落地，这些都对应用配置管理提出了更高的要求。

#### （1）**交付件和配置分离**

传统做法应用在打包部署时，会为不同环境打出不同配置的包，例如为开发/测试/UAT/生产环境分别制作发布包，每个包里包含环境特定配置。

现代微服务提倡云原生(Cloud Native)和不可变基础设施（Immutable Infrastructure）的理念，推荐采用如容器镜像这种方式打包和交付微服务，应用镜像一般只打一份，可以部署到不同环境。这就要求交付件（比如容器镜像）和配置进行分离，交付件只制作一份，并且是不可变的，可以部署到任意环境，而配置由配置中心集中管理，所有环境的配置都可以在配置中心集中配，运行期应用根据自身环境到配置中心动态拉取相应的配置。

#### （2）**抽象标准化**

企业应该由框架或者中间件团队提供标准化的配置中心服务(Configuration as a Service)，封装屏蔽配置管理的细节和配置的不同格式，方便用户进行自助式的配置管理。一般用户只需要关注两个抽象和标准化的接口：

* 配置管理界面UI，方便应用开发人员管理和发布配置；
* 封装好的客户端API，方便应用集成和获取配置；

#### （3）**多环境多集群**

现代微服务应用大都采用多环境部署，一般标准化的环境有开发/测试/UAT/生产等，有些应用还需要多集群部署，例如支持跨机房或者多版本部署。配置中心需要支持对多环境和多集群应用配置的集中式管理。

#### （4）**高可用**

配置中心必须保证高可用，不能随便挂，否则可能大面积影响微服务。在极端的情况下，如果配置中心不可用，客户端也需要有降级策略（如使用本地缓存配置），保证应用可以不受影响。

#### （5）**实时性**

配置更新需要尽快通知到客户端，这个周期不能太长，理想应该是实时的。有些配置的实时性要求很高，比方说主备切换配置或者蓝绿部署配置，需要秒级切换配置的能力。

#### （6）**治理**

配置需要治理，具体包括：

* 配置审计：谁、在什么时间、修改了什么配置，需要详细的审计，方便出现问题时能够追溯。
* 配置版本控制：每次变更需要版本化，出现问题时候能够及时回滚到上一版本。
* 配置权限控制：配置变更发布需要认证授权，不是所有人都能修改和发布配置。
* 灰度发布：高级的配置治理支持灰度发布，配置发布时可以先让少数实例生效，确保没有问题再逐步放量。

####

## 参考

[微服务架构 为什么需要配置中心](https://www.cnblogs.com/davidwang456/articles/9238281.html)

[一篇好TM长的关于配置中心的文章](http://jm.taobao.org/2016/09/28/an-article-about-config-center/)[<br>](http://img3.tbcdn.cn/5476e8b07b923/TB1ZzOJNpXXXXahXVXXXXXXXXXX)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://maxwell.gitbook.io/way-to-architect/zhong-jian-jian/pei-zhi-zhong-xin/pei-zhi-zhong-xin-shi-shen-me.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
