写点什么

携程 Apollo 配置中心架构深度剖析

  • 2018-06-07
  • 本文字数:3124 字

    阅读完需:约 10 分钟

一、介绍

Apollo(阿波罗)[参考附录] 是携程框架部研发并开源的一款生产级的配置中心产品,它能够集中管理应用在不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

Apollo 目前在国内开发者社区比较热,在 Github 上有超过 5k 颗星,在国内众多互联网公司有落地案例,可以说 Apollo 是目前配置中心产品领域 Number1 的产品,其成熟度和企业级特性要远远强于 Spring Cloud 体系中的 Spring Cloud Config 产品。

Apollo 采用分布式微服务架构,它的架构有一点复杂,Apollo 的作者宋顺虽然给出了一个架构图,但是如果没有一定的分布式微服务架构基础的话,则普通的开发人员甚至是架构师也很难一下子理解。为了让大家更好的理解 Apollo 的架构设计,我花了一点时间把 Apollo 的架构按我的方式重新剖析一把。只有完全理解了 Apollo 的架构,大家才能在生产实践中更好的部署和使用 Apollo。另外,通过学习 Apollo 的架构,大家可以深入理解微服务架构的一些基本原理。

二、架构和模块

下图是 Apollo 的作者宋顺给出的架构图:

Apollo 架构图 by 宋顺

如果没有足够的分布式微服务架构的基础,对携程的一些框架产品 (比如 Software Load Balancer(SLB)) 不了解的话,那么这个架构图第一眼看是不太好理解的 (其实我第一次看到这个架构也没有看明白)。在这里我们先放一下,等我后面把这个架构再重新剖析一把以后,大家再回过头来看这个架构就容易理解了。

下面是 Apollo 的七个模块,其中四个模块是和功能相关的核心模块,另外三个模块是辅助服务发现的模块:

四个核心模块及其主要功能

1. ConfigService

  • 提供配置获取接口
  • 提供配置推送接口
  • 服务于 Apollo 客户端

2. AdminService

  • 提供配置管理接口
  • 提供配置修改发布接口
  • 服务于管理界面 Portal

3. Client

  • 为应用获取配置,支持实时更新
  • 通过 MetaServer 获取 ConfigService 的服务列表
  • 使用客户端软负载 SLB 方式调用 ConfigService

4. Portal

  • 配置管理界面
  • 通过 MetaServer 获取 AdminService 的服务列表
  • 使用客户端软负载 SLB 方式调用 AdminService

三个辅助服务发现模块

1. Eureka

  • 用于服务发现和注册
  • Config/AdminService 注册实例并定期报心跳
  • 和 ConfigService 住在一起部署

2. MetaServer

  • Portal 通过域名访问 MetaServer 获取 AdminService 的地址列表
  • Client 通过域名访问 MetaServer 获取 ConfigService 的地址列表
  • 相当于一个 Eureka Proxy
  • 逻辑角色,和 ConfigService 住在一起部署

3. NginxLB

  • 和域名系统配合,协助 Portal 访问 MetaServer 获取 AdminService 地址列表
  • 和域名系统配合,协助 Client 访问 MetaServer 获取 ConfigService 地址列表
  • 和域名系统配合,协助用户访问 Portal 进行配置管理

三、架构剖析

Apollo 架构 V1

如果不考虑分布式微服务架构中的服务发现问题,Apollo 的最简架构如下图所示:

Apollo V1 架构 by 杨波

要点:

  1. ConfigService 是一个独立的微服务,服务于 Client 进行配置获取。
  2. Client 和 ConfigService 保持长连接,通过一种拖拉结合 (push & pull) 的模式,实现配置实时更新的同时,保证配置更新不丢失。
  3. AdminService 是一个独立的微服务,服务于 Portal 进行配置管理。Portal 通过调用 AdminService 进行配置管理和发布。
  4. ConfigService 和 AdminService 共享 ConfigDB,ConfigDB 中存放项目在某个环境的配置信息。ConfigService/AdminService/ConfigDB 三者在每个环境 (DEV/FAT/UAT/PRO) 中都要部署一份。
  5. Protal 有一个独立的 PortalDB,存放用户权限、项目和配置的元数据信息。Protal 只需部署一份,它可以管理多套环境。

Apollo 架构 V2

为了保证高可用,ConfigService 和 AdminService 都是无状态以集群方式部署的,这个时候就存在一个服务发现问题:Client 怎么找到 ConfigService?Portal 怎么找到 AdminService?为了解决这个问题,Apollo 在其架构中引入了 Eureka 服务注册中心组件,实现微服务间的服务注册和发现,更新后的架构如下图所示:

Apollo V2 架构 by 杨波

要点:

  1. Config/AdminService 启动后都会注册到 Eureka 服务注册中心,并定期发送保活心跳。
  2. Eureka 采用集群方式部署,使用分布式一致性协议保证每个实例的状态最终一致。

Apollo 架构 V3

我们知道 Eureka 是自带服务发现的 Java 客户端的,如果 Apollo 只支持 Java 客户端接入,不支持其它语言客户端接入的话,那么 Client 和 Portal 只需要引入 Eureka 的 Java 客户端,就可以实现服务发现功能。发现目标服务后,通过客户端软负载 (SLB,例如 Ribbon) 就可以路由到目标服务实例。这是一个经典的微服务架构,基于 Eureka 实现服务注册发现 + 客户端 Ribbon 配合实现软路由,如下图所示:

Apollo V3 架构 by 杨波

Apollo 架构 V4

在携程,应用场景不仅有 Java,还有很多遗留的.Net 应用。Apollo 的作者也考虑到开源到社区以后,很多客户应用是非 Java 的。但是 Eureka(包括 Ribbon 软负载) 原生仅支持 Java 客户端,如果要为多语言开发 Eureka/Ribbon 客户端,这个工作量很大也不可控。为此,Apollo 的作者引入了 MetaServer 这个角色,它其实是一个 Eureka 的 Proxy,将 Eureka 的服务发现接口以更简单明确的 HTTP 接口的形式暴露出来,方便 Client/Protal 通过简单的 HTTPClient 就可以查询到 Config/AdminService 的地址列表。获取到服务实例地址列表之后,再以简单的客户端软负载 (Client SLB) 策略路由定位到目标实例,并发起调用。

现在还有一个问题,MetaServer 本身也是无状态以集群方式部署的,那么 Client/Protal 该如何发现 MetaServer 呢?一种传统的做法是借助硬件或者软件负载均衡器,例如在携程采用的是扩展后的 NginxLB(也称 Software Load Balancer),由运维为 MetaServer 集群配置一个域名,指向 NginxLB 集群,NginxLB 再对 MetaServer 进行负载均衡和流量转发。Client/Portal 通过域名 +NginxLB 间接访问 MetaServer 集群。

引入 MetaServer 和 NginxLB 之后的架构如下图所示:

Apollo V4 架构 by 杨波

Apollo 架构 V5

V4 版本已经是比较完成的 Apollo 架构全貌,现在还剩下最后一个环节:Portal 也是无状态以集群方式部署的,用户如何发现和访问 Portal?答案也是简单的传统做法,用户通过域名 +NginxLB 间接访问 Portal 集群。

所以 V5 版本是包括用户端的最终的 Apollo 架构全貌,如下图所示:

Apollo V5 架构 by 杨波

四、结论

1. 经过我在第三部分的剖析之后,相信大家对 Apollo 的微服务架构会有更清晰的认识,作为一个思考题,大家再回头看一下第二部分宋顺给出的架构图,现在是否能够理解?它和我的架构是如何对应的?提示一下,宋顺的视角是一个从上往下的俯视视角,而我的是一个侧面视角。

2. ConfgService/AdminService/Client/Portal 是 Apollo 的四个核心微服务模块,相互协作完成配置中心业务功能,Eureka/MetaServer/NginxLB 是辅助微服务之间进行服务发现的模块。

3. Apollo 采用微服务架构设计,架构和部署都有一些复杂,但是每个服务职责单一,易于扩展。另外,Apollo 只需要一套 Portal 就可以集中管理多套环境 (DEV/FAT/UAT/PRO) 中的配置,这个是它的架构的一大亮点。。

4. 服务发现是微服务架构的基础,在 Apollo 的微服务架构中,既采用 Eureka 注册中心式的服务发现,也采用 NginxLB 集中 Proxy 式的服务发现。

我近期和极客时间合作,结合自己多年在一线企业的架构建设实战经验,推出《微服务架构实践 160 讲》视频课程,通过原理讲解和实践操作的方式,帮助你从 0 到 1 深入理解主流微服务技术栈组建及架构,踏上从程序员到架构师的进阶之路。

另外,新一期的课程中,我还邀请到 Apollo 配置中心作者宋顺老师现身说法,为大家带来 Apollo 的系统介绍。

五、附录

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

2018-06-07 18:0136034

评论 3 条评论

发布
用户头像
写得太好了,一下就看懂了。
2022-11-17 11:17 · 上海
回复
用户头像
清晰明了
2021-08-08 16:49
回复
用户头像
深度好文呀。
2018-11-10 23:33
回复
没有更多了
发现更多内容

兄弟们,这年头,咱移动客户端工程师还有前途吗,flutter图片压缩上传

android 程序员 移动开发

全面复盘Android开发者容易忽视的Backup功能 _ 创作者训练营第二期

android 程序员 移动开发

关于Android的渲染机制,大厂面试官最喜欢问的7个问题【建议收藏

android 程序员 移动开发

从面试无人问津到手拿百度offer,还原一段野生程序员的成长经历

android 移动开发

他经历了什么?七年资深Android程序员想转学Java,网友纷纷留言劝阻

android 程序员 移动开发

做Android开发摸鱼是要付出代价的,被主管劝退,我后悔了

android 程序员 移动开发

做了5年Android,靠着这份190页的面试资料,成功入职腾讯

android 程序员 移动开发

做了六年Android,终于熬出头了,15K到31K全靠这份高级面试题

android 程序员 移动开发

新消费:如何让企业持续增长

石云升

学习笔记 11月日更 新消费

做android开发一直不相信35岁危机,好像被自己遇到了,android系统开发面试

android 程序员 移动开发

全面理解 Flutter(万字长文,深度解析,整理了3家面试问题:美团+字节+腾讯

android 程序员 移动开发

代理模式,薪资翻倍

android 程序员 移动开发

使用DataBinding还在为数据处理头疼?这篇文章帮你解决问题

android 程序员 移动开发

做了5年Android,靠着这份190页的面试资料,成功入职字节跳动

android 程序员 移动开发

架构实战营模块毕业总结

河马先生

架构实战营

关于 Flutter 是不是“大有可为”这件事,androidjetpack教程

android 移动开发

架构实战营毕业设计

宁静志远

六年Android从迷茫到大牛的成长之路,不忘初心,方得始终

android 程序员 移动开发

使用二阶贝塞尔曲线实现添加购物车动画,移动互联网开发专业

android 程序员 移动开发

做Android开发,如何使用 Kotlin 提高生产力!,android开发前景2019

android 程序员 移动开发

全网都刷爆了,不会只有你不知道吧—,android智能手机编程答案

android 程序员 移动开发

全面!2020华为Android岗面试真题(已解析含答案,android蓝牙开发框架

android 程序员 移动开发

架构实战营-模块九-毕业设计

Cingk

做了5年Android,靠着这份面试题跟答案,我从12K变成了30K

android 程序员 移动开发

linux系列之: 你知道查看文件空间的两种方法吗?

程序那些事

Linux 操作系统 程序那些事 11月日更

你曾遇到的某大厂奇葩问题:Android组件化开发,组件间的Activity页面跳转

android 程序员 移动开发

借腾讯开源 VasDolly,谈谈 Android 签名和多渠道打包的原理!

android 程序员 移动开发

MySQL锁的分类知多少

卢卡多多

MySQL锁 11月日更

做了3年大厂HR,这几种程序员我会直接pass掉!,网站开发前后端分离

android 程序员 移动开发

做Android开发的,要做到什么水平,才能年薪百万,阿里P7深入Binder原理讲解

android 程序员 移动开发

入职两年的安卓“程序员“跳槽,2021年阿里Android面试题精选

android 程序员 移动开发

携程Apollo配置中心架构深度剖析_架构_杨波_InfoQ精选文章