写点什么

携程 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:0136199

评论 3 条评论

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

SpringloC容器的依赖注入源码解析(3)

爱好编程进阶

Java 程序员 后端开发

【解决】jsPDF之长图片生成PDF

爱好编程进阶

Java 程序员 后端开发

如何在缺乏商业项目经验的前提下成功通过面试,兼说我如何甄别非商业项目经验

爱好编程进阶

Java 程序员 后端开发

Kafka的体系结构

爱好编程进阶

Java 程序员 后端开发

SpringBoot整合MyBatis完整详细版

爱好编程进阶

Java 程序员 后端开发

厉害了!把 HashMap 剖析的只剩渣了!

爱好编程进阶

Java 程序员 后端开发

史上最全图解JVM,京东小哥带你了解性能提升100%背后的秘密武器

爱好编程进阶

Java 程序员 后端开发

JUC常见的锁

爱好编程进阶

程序员 后端开发

SpringBoot-MVC自动配置原理

爱好编程进阶

Java 程序员 后端开发

「2021-老胡的年终总结」

爱好编程进阶

程序员 后端开发

一文聊透 Netty IO 事件的编排利器 pipeline | 详解所有 IO 事件的触发时机以及传播路径

bin的技术小屋

网络编程 Netty java netty 5月月更

MySQL数据库所有知识点最详细讲解,内置官方文档、个人理解

爱好编程进阶

程序员 后端开发

SpringDataJPA之关联关系

爱好编程进阶

Java 程序员 后端开发

JAVA-使用注解实现Excel表头多语言导出

JayJay

5月月更

【刷题第十天】21. 合并两个有序链表

白日梦

5月月更

摆平各类目标检测识别AI应用,有它就够了!

华为云开发者联盟

计算机视觉 CANN 昇腾 目标检测识别 YoloV3

Java必备技能之源码篇(Nginx源码研究之nginx限流模块)

爱好编程进阶

Java 程序员 后端开发

java高并发系列 - 第28天:实战篇,微服务日志的伤痛

爱好编程进阶

Java 程序员 后端开发

【Jvm】Jvm类加载机制

爱好编程进阶

Java 程序员 后端开发

【直播预告】程序员修炼之道——如何实现敏捷开发与稳健运行的有机统一

FinClip

程序员 小程序运营

AI简报-视频去交错(Deinterlance)

AIWeker

人工智能 深度学习 5月月更 去交错

极光笔记 | 极光基于元数据驱动数据治理浅谈

极光GPTBots-极光推送

数据治理 元数据

使用APICloud AVM多端框架开发企业移动OA办公的项目实践

YonBuilder低代码开发平台

企业应用 APP开发 APICloud 多端开发 avm.js

讨论两种Redis中Token的存储方式

华为云开发者联盟

Token key 存储token userid

leetcode38

爱好编程进阶

程序员 后端开发

Tomcat介绍(三)

爱好编程进阶

程序员 后端开发

「每日一问」并发编程的特性是什么

爱好编程进阶

Java 程序员 后端开发

编写自己的 WordPress 模板

海拥(haiyong.site)

WordPress 5月月更

令人欣慰!阿里大牛把Spring微服务架构设计整理成了500多页文档,真香

爱好编程进阶

Java 程序员 后端开发

优化了MYSQL大量写入问题,老板奖励了1000块给我

爱好编程进阶

Java 程序员 后端开发

大佬总结的4条宝贵经验,送给初入职场的你,从此一飞冲天

爱好编程进阶

Java 程序员 后端开发

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