配置中心的定义
配置中心的目的是什么?或者说我们为什么需要配置中心呢?要回答这个问题我们可以反向思考下,如果没有配置中心会是什么情景。如果没有统一配置中心我们应用的配置参数配置在文件里,随着程序功能的日益复杂,程序的配置日益增多,比如各种功能开关、参数的配置、服务器的地址等。首先是管理起来不方便,其次是这种静态式的配置做完修改后每次都需要重启,而且互联网应用程序对于配置的期望也越来越高,比如需要配置实时生效、灰度发布、分环境、分集群管理配置,又比要求完善的权限、审核机制等等。所以我们需要统一的配置中心。
并不是所有的轮子都需要我们自己来造,如果有优秀的开源产品我们直接使用就行了。那我们首先来看一下市面上有哪些优秀的开源的配置中心产品。
Spring Cloud Config 淘宝的diamond 百度Disconf 携程Apollo
首先Spring Cloud Config是Spring出品的和Spring Cloud能够无缝集成。其次淘宝的diamond是淘宝针对Spring框架定制,但是已经不在维护了。然后百度Disconf也是针对Spring的,非Spring 项目暂时无法使用。最后是携程的Apollo,是携程框架部门研发的分布式配置中心,能够集中化的管理应用不同环境、不同集群配的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,非常实用于微服务配置管理场景。

经过对比可以发现Spring Cloud现在功能海很弱,而百度的Disconf依赖的组件是zookeeper,而其实配置中心要求的是AP模型。携程的Apollo是AP模型,并且功能也比较强大,业界内配置中心的开源选择基本上也是Apollo。
统一管理不同环境、不同集群的配置 配置修改实时生效 版本发布管理 权限管理、发布审核、操作审计 客户端配置信息监控 提供Java和.Net原生客户端 部署简单 提供开发平台API
Apollo提供了一个统一的界面集中式管理不同环境(enviroment)、不同集群(cluster)、不同命名空间(namespace)的配置。用户在Apollo修改完配置并发布以后,客户端能实时大约1秒接受到最新的配置,并通知到应用程序。Apollo所有的配置发布都有版本概念,从而可以方便的支持配置的回滚。Apollo支持权限管理、发布审核、操作审计等功能,并且还可以清晰的看到配置在被哪些实例使用。为了方便应用服务与配置中心进行通信,Apollo提供了原生的Java和.net客户端,同时还提供了http接口,非Java和.net应用也可以很方便的使用。从部署的简易性来说,Apollo完全满足配置中心作为基础服务,可用性要求非常高,对外部依赖少的特性。Appolo目前仅仅依赖MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来,同时Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数。最最方便的是,Apollo提供开发平台API,对于有些历史遗留项目,它们的配置可能会有比较复杂的格式,如XML、JSON,需要对各式做校验,Apollo提供开放接口自定义。

用户在配置中心对配置进行修改并发布
配置中心通知Apollo客户端有配置更新
Apollo客户端从配置中心拉去最新的配置、更新本地配置并通知应用
Apollo界面概览

Apollo的核心概念
* application(应用)* 实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置。* 每个应用都需要有唯一的身份标识appId,我们认为应用身份是跟着代码走的,所以需要在代码中配置。* enviroment(环境)* 配置对应的环境,Apollo客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置。* 我们认为环境和代码无关,同一份代码配置在不同的环境应该能够获取到不同的配置。* 所以环境默认是通过读取机器上的配置(server.properties中的env属性)指定的,不过为了开发方便,我们也支持运行时通过System Property等指定。* cluster(集群)* 一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。* 对不同的cluster,同一个配置可以有不一样的值,如Zookeeper地址。* 集群默认是通过读取机器上的配置(server.properties中的idc属性)指定的,不过也支持运行时通过System Property指定,具体信息请参见Java客户端使用指南。* namespace(命名空间)* 一个应用下不同配置的分组,可以简单的把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件、RPC配置文件,应用自身配置文件。

* Config Service提供配置的读取、推送等功能、服务对象是Apollo客户端。* Admin Service提供配置的修改、发布等功能,服务对象是Apollo客户端。* Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳。* 在Eureka之上有一层Meta Server用户封装Eureka的服务发现接口。* Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),然后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试。* Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试。* Apollo为了简化部署,实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中。
Apollo客户端设计

* 客户端和服务端保持一个长连接,从而能第一时间获得配置更新的推送* 客户端还会定时从Apollo配置中心服务端拉去应用的最新配置* 这是一个fallback机制,为了防止推送机制失败导致配置不更新* 客户端定时拉去会上报本地版本,所以一般情况下,对于定时拉去的操作,服务端都会返回304-NotModified* 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property:apollo.refreshInterval来覆盖,单位为分* 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中* 客户端会把从服务端获取到的配置在本地文件系统中缓存一份* 在遇到服务不可用,或者网络不通的时候,依然能够从本地恢复配置* 应用程序从Apollo客户端获取最新的配置、订阅配置更新通知
* 长连接实际上是基于HTTP Long Polling实现* 客户端发起一个HTTP请求到服务端* 服务端会保持住这个连接60秒* 如果在60秒内有客户端关心的配置变化,被保持住的客户端请求会立即返回,并告知客户端有配置变化的namespace信息,客户端会依据此拉取对应namespace的最新配置* 如果在60秒内没有客户端关心的配置变化,那么会返回HTTP状态码304给客户端* 在收到服务端请求后会立即重新发器连接,回到第一步* 考虑到会有数万客户端向服务端发起长连接,在服务采用了asyn servelt来服务HTTP Long Polling请求。
配置中心作为基础服务,可用性要求非常高,下面的表格描述了不同场景下Apollo的可用性:

关于配置中心没有太多说法,开源的产品推荐大家用携程Apollo即可,毕竟大家都在用。




