携程Apollo配置中心架构介绍

news2024/12/23 23:35:14

俗话说”麻雀虽小,五脏俱全“,有人说想看开源源码却不知道什么好,事实上,那些流行多年,广受好评的开源工程都是很值得一读的。今天我们介绍Apollo配置中心的基本情况,之所以介绍这个,主要是因为公司里用的配置中心就是这个,最近要做一次技术分享, 所以就调研了一下发现很多设计非常简介高效,值得学习,这里整理几个最重要的内容。

目录

1.介绍

1.1 介绍

1.2 架构演进

1.2.1 Apollo架构V1

1.2.2 Apollo架构V2

1.2.3 Apollo架构V3

1.2.4 Apollo架构V4

1.2.5 Apollo架构V5

1.3 主要模块

1.3.1 四个核心模块

1.3.2 三个辅助服务发现模块

1.4 核心工作流程

2. 消息推送流程

2.1 发送ReleaseMessage的实现方式

2.2 Config Service通知客户端的实现方式

2.3 客户端设计

参考文献


1.介绍

1.1 介绍

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

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

Apollo的整体流程如下:

  1. 用户在配置中心对配置进行修改并发布

  2. 配置中心通知Apollo客户端有配置更新

  3. Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用

1.2 架构演进

1.2.1 Apollo架构V1

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

Apollo V1架构

要点:

  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只需部署一份,它可以管理多套环境。

1.2.2 Apollo架构V2

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

要点:

  1. Config/AdminService启动后都会注册到Eureka服务注册中心,并定期发送保活心跳。

  2. Eureka采用集群方式部署,使用分布式一致性协议保证每个实例的状态最终一致。

1.2.3 Apollo架构V3

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

1.2.4 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之后的架构如下图所示:

1.2.5 Apollo架构V5

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

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

1.3 主要模块

1.3.1 四个核心模块

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

  1. ConfigService

    • 提供配置获取接口

    • 提供配置推送接口

    • 服务于Apollo客户端

  2. AdminService

    • 提供配置管理接口

    • 提供配置修改发布接口

    • 服务于管理界面Portal

  3. Client

    • 为应用获取配置,支持实时更新

    • 通过MetaServer获取ConfigService的服务列表

    • 使用客户端软负载SLB方式调用ConfigService

  4. Portal

    • 配置管理界面

    • 通过MetaServer获取AdminService的服务列表

    • 使用客户端软负载SLB方式调用AdminService

    • 基于Angular做的

1.3.2 三个辅助服务发现模块

  1. Eureka

    • 用于服务发现和注册

    • Config/AdminService注册实例并定期报心跳

    • 和ConfigService住在一起部署

  2. MetaServer

    • 主要用于跨语言支持

    • Portal通过域名访问MetaServer获取AdminService的地址列表

    • Client通过域名访问MetaServer获取ConfigService的地址列表

    • 逻辑角色,和ConfigService住在一起部署

  3. NginxLB

    • 也主要针对跨语言支持的

    • 和域名系统配合,协助Portal访问MetaServer获取AdminService地址列表

    • 和域名系统配合,协助Client访问MetaServer获取ConfigService地址列表

    • 和域名系统配合,协助用户访问Portal进行配置管理

1.4 核心工作流程

官网有比较明确的说明,详细参考Apollo

核心是:Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试。

2. 消息推送流程

在配置中心中,最重要的功能就是配置发布后实时推送到客户端。下面我们简要看一下这块是怎么设计实现的。

  上图简要描述了配置发布的大致过程:

  1. 用户在Portal操作配置发布

  2. Portal调用Admin Service的接口操作发布

  3. Admin Service发布配置后,发送ReleaseMessage给各个Config Service

  4. Config Service收到ReleaseMessage后,通知对应的客户端

2.1 发送ReleaseMessage的实现方式

Admin Service在配置发布后,需要通知所有的Config Service有配置发布,从而Config Service可以通知对应的客户端来拉取最新的配置。

从概念上来看,这是一个典型的消息使用场景,Admin Service作为producer发出消息,各个Config Service作为consumer消费消息。通过一个消息组件(Message Queue)就能很好的实现Admin Service和Config Service的解耦。

在实现上,考虑到Apollo的实际使用场景,以及为了尽可能减少外部依赖,没有采用外部的消息中间件,而是通过数据库实现了一个简单的消息队列。

这个工作过程就是一侧负责插入数据到DB,然后几个客户端定时扫描表,如果找到自己要处理的类型,就启动执行。具体实现方式如下:

  1. Admin Service在配置发布后会往ReleaseMessage表插入一条消息记录,消息内容就是配置发布的AppId+Cluster+Namespace,参见DatabaseMessageSender

  2. Config Service有一个线程会每秒扫描一次ReleaseMessage表,看看是否有新的消息记录,参见ReleaseMessageScanner。

  3. Config Service如果发现有新的消息记录,那么就会通知到所有的消息监听器ReleaseMessageListener,例如NotificationControllerV2,消息监听器的注册过程参见ConfigServiceAutoConfiguration

  4. NotificationControllerV2得到配置发布的AppId+Cluster+Namespace后,会通知对应的客户端。

2.2 Config Service通知客户端的实现方式

上一节中简要描述了NotificationControllerV2是如何得知有配置发布的,那NotificationControllerV2在得知有配置发布后是如何通知到客户端的呢?

实现方式如下:

  1. 客户端会发起一个Http请求到NotificationControllerV2

  2. NotificationControllerV2不会立即返回结果,而是通过Spring DeferredResult把请求挂起。

  3. 如果在60秒内没有该客户端关心的配置发布,那么会返回Http状态码304给客户端。

  4. 如果有该客户端关心的配置发布,NotificationControllerV2会调用DeferredResult的setResult方法,传入有配置变化的namespace信息,同时该请求会立即返回。客户端从返回的结果中获取到配置变化的namespace后,会立即请求Config Service获取该namespace的最新配置。

2.3 客户端设计

 上图简要描述了Apollo客户端的实现原理:

  1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)

  2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。

    • 这是一个fallback机制,为了防止推送机制失效导致配置不更新

    • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified

    • 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟。

  3. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中

  4. 客户端会把从服务端获取到的配置在本地文件系统缓存一份。在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置

  5. 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知

参考文献

Apollo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/100589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线地图持续进化,BAT技术“鲜”发制人

配图来自Canva可画 眼下,在线地图正在成为智能穿戴、物流运输、旅游度假等诸多领域的“基础设施”,尤其是自动驾驶、车路协同等汽车细分赛道越来越重视在线地图的导入。 得益于此,在线地图市场持续走向火热。华经产业研究院数据显示&#x…

linux基础学习-ssh基础

ssh基础 通过SSH客户端我们可以连接到运行了SSH服务器的远程机器上 SSH客户端是一种使用Secure Shell(SSH)协议连接到远程计算机的软件程序目前较为可靠,专门为远程登录会话和其他网络服务提供安全性的协议 利用SSH协议可以有效防止远程管理过程中的信息泄露提供SS…

行业级开源无人机目标追踪,高空助力抓贼!

活久见!成都一高楼惊险无人机抓小偷视频中危险动作,请勿模仿! 本次实验中我们使用的是Prometheus 600(P600)行业级无人机研发平台(此平台适用于无人机行业应用开发与室外环境下的无人机算法验证&#xff0…

White Rose设计与架构的想法分享

在七牛云校园黑客马拉松中,一款设计优秀、逻辑清晰的白板作品脱颖而出,获得第二名的好成绩,这就是来自郑州大学Since团队的White Rose白板,以下是他们的设计和架构分享。 一、前言 White Rose是参加七牛云hackathon比赛的作品&am…

【】Fate单机部署及代码调试全流程ongoing

这里写自定义目录标题Fate单机部署及代码调试全流程一、安装Linux系统或者虚拟机-Linux系统1、先装虚拟机2、在虚拟机上安装Ubuntu系统二、FATE单机部署并PyCharm如何连接远程服务器的docker容器进行运行和调试代码【整体未成功,可跳过】三、Ubuntu系统上安装anacon…

谈谈什么是才是InnoDB解决幻读的最佳方案

本文会分享一下MySQL的InnoDB引擎下的事务幻读问题与解决方案--LBCC&MVCC。经过好几天的熬夜通宵,终于把这部分的内容捋清楚了。至于为什么说是InnoDB呢?因为MyISAM引擎是不支持事务的。 事务 概念 一个事情由n个单元组成,这n个单元在…

Apache 虚拟主机里的 ServerName 指令

术语虚拟主机(Virtual host)是指在一台机器上运行多个网站(例如 company1.example.com 和 company2.example.com)的做法。 虚拟主机可以是“基于 IP”的,这意味着每个网站都有不同的 IP 地址,也可以是“基于名称的”,…

Springboot集成Neo4j

一、概述 1.为什么图形数据库? 生活在一个互联的世界中,大多数领域需要处理丰富的连接集以了解真正发生的事情。通常,我们发现项目之间的联系与项目本身一样重要。 虽然现有的关系数据库可以存储这些关系,但它们通过昂贵的JOIN操作…

微服务框架 SpringCloud微服务架构 服务异步通讯 50 消息可靠性 50.3 消费者消息确认

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 服务异步通讯 文章目录微服务框架服务异步通讯50 消息可靠性50.3 消费者消息确认50.3.1 消费者确认50 消息可靠性 50.3 消费者消息确认 50…

OTA前装搭载率逼近50%,哪些供应商正在领跑细分赛道

智能汽车的OTA,正在进入新发展周期。 早期的OTA,主要围绕座舱信息娱乐、T-BOX及少部分车内其他ECU,主要目的是修复软件Bug以及改进用户体验,降低整车的召回成本。这个阶段,OTA对应的整车电子架构还是以传统的分布式EC…

前端上传文件或者上传文件夹

文档 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input 上传文件夹&#xff0c;主要的参数webkitdirectory 浏览器上传文件夹&#xff0c;浏览器会弹出询问窗口 兼容性 https://caniuse.com/?searchwebkitdirectory 代码如下 <!-- 选择文件 -->…

【Anime.js】——Anime.js源码之引擎的理解

一、Anime.js整体结构 Anime.js的强大之处在于代码量非常少&#xff0c;但功能却非常强大。让我们一起来探索Anime.js源码的核心吧~ Anime.js之所以能如此强大主要是因为它的代码结构设计的非常巧妙合理&#xff0c;所以我们想要掌握Anime.js的核心&#xff0c;首先我们要了解…

CUDA入门和网络加速学习(四)

0. 简介 最近作者希望系统性的去学习一下CUDA加速的相关知识&#xff0c;正好看到深蓝学院有这一门课程。所以这里作者以此课程来作为主线来进行记录分享&#xff0c;方便能给CUDA网络加速学习的萌新们去提供一定的帮助。 1. Cublas概念 cuBLAS是一个BLAS的实现&#xff0c;…

低代码常见场景【下】|行业示例

全文 3131 字 阅读时间约 9 分钟 本文首发于码匠技术博客 目录 低代码的行业示例 低代码在业务用例中的优势 关于码匠 阅读完上一篇文章后&#xff08;低代码用例【上】&#xff5c;如何解决业务问题&#xff09;&#xff0c;想必您已经对低代码的通用用例以及低代码如何解…

PolarDB-X源码解读:DDL的一生(下)

概述 在《DDL的一生&#xff08;上&#xff09;》中&#xff0c;我们以添加全局二级索引为例&#xff0c;从DDL开发者的视角介绍了如何在DDL引擎框架下实现一个逻辑DDL。在本篇&#xff0c;作者将从DDL引擎的视角出发&#xff0c;向读者介绍DDL引擎的架构、实现&#xff0c;以…

应用于高速收发模块的并行光学WDM波分光学技术

光模块的传输距离分为短距、中距、长距。通常短距离传输是指2km以下的传输距离&#xff0c;中距为10-20km。≥30km的则为长距离传输。根据不同的传输距离&#xff0c;光模块类型分为SR&#xff08;100m&#xff09;、DR&#xff08;500m&#xff09;、FR&#xff08;2km&#x…

实战三十二:基于knn算法的用户购物消费预测代码+数据

K近邻算法通过计算被分类对象与训练集对象之间的距离,确定其k个临近点,然后使用这k个临近点中最多的分类作为分类结果。 如上图,当K=3时,它会被分类为 Class B。因为K=3时,3个临近点里有2个是B类的。 同理,K=7时它会被分类为 Class A,因为K=7时,7个临近点里4个是A类的…

Clion开发stm32之下载程序记录

Clion开发stm32之下载程序 前提条件 安装openocd安装clion安装arm-gcc环境安装 MinGW(或Mysys2) 注意事项 !!! 开发路径必须要选择英文路径(中文路径会编译不通过的) 说明 这里为了在之后的项目里面使用配置文件。我们需要到openocd提供的board目录下添加自己的配置信息(…

gcc编译

gcc编译可执行程序有4个步骤&#xff1a;预处理、编译、汇编、链接。编译阶段消耗时间、系统资源最多。 从源文件hello.c到目标可执行文件hello&#xff0c;可以按照下面的执行命令&#xff0c;一步一步生成。 gcc -E hello.c -o hello.i gcc -S hello.i -o hello.s gcc -c he…

信息采编功能扩展开发心得

AEAI Portal门户为前端页面集成层而设计&#xff0c;在使用上简单、便捷&#xff0c;即使是非技术人员&#xff0c;通过操作文档也能够很好地将网站配置出来&#xff0c;不需要自身有很强的代码能力。同时门户平台搭配数通畅联的其他产品和组合方案&#xff0c;能够帮助企业快速…