携程开源项目——Apollo的设计与实现

4,735 阅读6分钟


内容来源:2017 年 7 月 22 日,携程框架研发部技术专家宋顺在“携程技术沙龙 | 海量互联网基础架构”进行《携程开源配置中心Apollo的设计与实现》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:2580 | 7分钟阅读

嘉宾演讲视频及PPT回顾:suo.im/4rpE22

摘要

随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址。对程序配置的期望值也越来越高:配置修改后实时生效,分环境、分集群管理配置,完善的权限、审核机制。在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。Apollo配置中心应运而生!

What is Apollo

Apollo是携程框架配置部门开源的统一应用配置中心,支持从4个维度管理配置,分别是Appllication(应用)、environment(环境)、Cluster(集群)、namespace(命名空间)。

What is Configuration

配置是独立于程序的只读变量,程序可以通过读取配置来改变自身的行为,但是不应该去改变配置。配置伴随着应用的整个生命周期,启动时读取配置,运行时根据配置调整行为。配置还可以有多种加载方式,比如程序内部hard code、配置文件、环境变量,启动参数、基于数据库等。

由于配置是可以改变程序的行为的,错误的配置就会导致程序的故障,所以对配置的修改和发布都需要一套完善的权限管理,另外配置在不同的环境和集群是存在差别的,这就需要有良好的管理。

Why Apollo

Apollo是一个有治理能力的配置管理平台,它提供了统一管理不同环境、不同集群的配置,并且配置的修改是实时生效的。每一次配置的修改发布都会形成新的版本,能够方便配置出错时进行回滚。

Apollo支持灰度发布,对某些重要功能可以事先在多个机器上试运行,没有问题后再发布。它还提供了权限管理、发布审核、操作审计的功能,并且能够对客户端配置信息进行监控。顺带一提Apollo有着java和.net的原生客户端,对Spring也有很好的支持。

Apollo at a glance

上图是Apollo的配置中心界面,左上方是一个环境列表,列出了当前应用的所有环境,下方是一些项目信息。右侧的两部分可以简单的认为是两个文件,其中Application每个应用都具备,默认的配置管理通过表格形势展现,可以看到这其中还有更改历史、修改人之类的信息以及一些功能按钮。

添加/修改配置项

Apollo中添加修改配置项可以通过新建或修改配置的按钮直接操作。需要注意的是修改的配置不会即时生效,而是需要点击发布后才能生效。

客户端获取配置(Java API样例)

可以看到首先我们要获取config对象,然后调用getIntProperty方法并传入key和默认值,通过这种方式可以获取到程序的最新值。

而通过上面的代码可以让开发人员实时的获取到配置的变化,Apollo提供了事件触发机制,只需要添加一个addChangeListener就行了,每次配置变化的时候会调用onChange方法,并且传入对应配置变化的事件,这个事件包含配置项的改变。

Spring 集成样例

对于Spring集成的简单用法只需要在AppConfig类上添加EnableApolloConfig。实际的配置中我们还是建议使用下方的方式,它同样支持配置变化事件。

Apollo in depth

之前提到过Apollo支持4个维度,在应用维度中,处于运行时状态下,Apollo可以通过唯一标识的appId来识别应用。环境维度中,我们认为环境信息与代码无关,只跟当前代码部署机体有关,所以默认这类信息存放在机器上。

第三个维度是集群,它相当于一个应用下不同实例的分组,集群既可以是物理性的也可以是逻辑性的。对于不同的集群可以有不一样的配置,我们默认数据中心作为集群。

最后的维度namespace(命名空间)是比较抽象的概念,简单理解就是一个应用下不同配置的分组,应用默认有自己的配置namespace-application,也可以使用公共组件的配置。

总体设计

图中最下方的Config Serivce主要提供配置的读取、推送等功能,服务对象是客户端。Admin Service则是提供对配置的修改、发布、审计这些功能,服务对象是Apollo服务界面。这两个服务都是多实例无状态部署。

再往上层的Mate Server主要是用来封装Eureka服务搭建的接口。在实际的调用中,客户端首先会从Mate Server获取所关心的服务的地址列表,之后直接通过IP和端口访问对应接口。

为了实际部署时候的方便,Mate Server、Eureka、Config Service都被部署到一个节点上。

Why Eureka?

Eureka提供了完整的服务注册和发布的实现,并且还能与Spring Cloud无缝集成,通过这样的集成就可以将本来依赖外部的Eureka变成了内部实现。同时因为Eureka是开源的,所以能够比较快的去发现问题,了解实现原理。

客户端设计

客户端的运行时和应用是在同一个容器中,应用在启动时客户端会做初始化向配置中心拉取配置,获取到的配置在应用的内存和本地文件分别缓存一份。同时客户端和服务端会保持长连接,以保证能实时的感知到配置的变化。

配置更新推送

客户端发起长连接,服务端默认保持30秒连接,这期间配置发生变化就返回,若一直没有发生改变服务端就断开连接,客户端自动重连。为了保证服务端的长连能力,我们使用了异步servlet,实现了Spring DeferredResult。

可用性考虑

Contribute to Apollo

Github地址:https://github.com/ctripcorp/apollo

服务端基于Spring Cloud和Spring Boot开发