Apollo架构设计

Apollo有一点很好,就是它是由国内携程团队开发,而且文档写的很全,代码也完全开源。如果去了解它也可以直接去看它的官方文档。

一、配置中心概念

1、背景

在实际开发中都会与配置打交道,举个简单例子,我们开发项目肯定会连接数据库,mysql也好oracle也好。那么我们 本地环境 和 线上环境 连接的数据肯定是不一样的,

那如果没有配置中心,我们要做的就是在发布前把本地数据库配置信息改成线上环境,如果仅仅是切换数据库那倒还好,但随着程序功能的日益复杂,程序的配置日益

增多比如,各种功能的开关参数的配置服务器的地址。同时对程序配置的期望值也越来越高:配置修改后 实时生效灰度发布分环境

分集群管理配置完善的权限审核机制。在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。

Apollo配置中心应运而生!

2、配置分类和场景

在现代开发中配置的分类还是蛮多的,下面借用杨波老师的一张图,来看下目前比较常见的分类及场景。

3、开关驱动开发

在我们实际开发业务中,开关这个概念其实是非常常见的,有些时候是需要用户在页面去进行开关操作,那么我们一般数据库新建配置表来存储用户操作的开关。

但有些时候是不需要用户去操作的,只需我们后台开发人员进行配置开关的,那其实就不需要在数据库去建一个配置表,而是通过配置中心就可以完成了。

二、Apollo配置中心概念

1、简介

Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、

流程治理等特性。

2、优点

Apollo作为为配置中心,有着非常多的优点。

3、四个维度

Apollo支持4个维度管理Key-Value格式的配置:

1、application (应用)
2、environment (环境)
3、cluster (集群)
4、namespace (命名空间)

1、application

1、Apollo 客户端在运行时需要知道当前应用是谁,从而可以根据不同的应用来获取对应应用的配置。

2、每个应用都需要有唯一的身份标识,可以在代码中配置 app.id 参数来标识当前应用,Apollo 会根据此指来辨别当前应用。

2、environment

在实际开发中,我们的应用经常要部署在不同的环境中,一般情况下分为 开发、测试、生产 等等不同环境,不同环境中的配置也是不同的,在 Apollo 中默认提供了

四种环境:

FAT:功能测试环境

UAT:集成测试环境

DEV:开发环境

PRO:生产环境

在程序中如果想指定使用哪个环境,可以配置变量 env 的值为对应环境名称即可。

3、cluster

1、一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。

2、对不同的集群,同一个配置可以有不一样的值,比如说上面所指的两个北京、上海两个机房设置两个集群,都有 mysql 配置参数,其中参数中配置的地址是不一样的。

4、namespace

一个应用中不同配置的分组,可以简单地把 namespace 类比为不同的配置文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC 配置文件等。

熟悉 SpringBoot 的都知道,SpringBoot 项目都有一个默认配置文件 application.yml,如果还想用多个配置,可以创建多个配置文件来存放不同的配置信息,通过

指定 spring.profiles.active 参数指定应用不同的配置文件。这里的 namespace 概念与其类似,将不同的配置放到不同的配置 namespace 中。

Namespace 分为两种权限,分别为:

  • public(公共的): public权限的 Namespace,能被任何应用获取。
  • private(私有的): 只能被所属的应用获取到。一个应用尝试获取其它应用 private 的 Namespace,Apollo 会报 “404” 异常。

5、本地缓存

Apollo客户端会把从服务端获取到的配置在 本地文件系统缓存 一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行。

本地缓存路径默认位于以下路径,所以请确保 /opt/data或C:\opt\data\目录存在,且应用有读写权限

  • Mac/Linux: /opt/data/{appId}/config-cache
  • Windows: C:\opt\data{appId}\config-cache

本地配置文件会以下面的文件名格式放置于本地缓存路径下:

{appId}+{cluster}+{namespace}.properties

三、Apollo和SpringCloudConfig的对比

网上有一张图总结的很完整

总结

1、SpringCloudConfig优势是对SpringBoot原生支持,且是SpringCloud组件。缺点是 无界面管理且需要git,SpringCloudBus、Mq支持其动态更新

2、Apollo优势是技术栈单一,仅需要Mysql就可以支持动态更新配置,便于维护。缺点是不是SpringCloud体系,虽然开源,版本更新也活跃,但是对SpringCloud的

一、整体架构

Apollo整体架构图,已由作者宋顺已经给出:

这幅图所描述的已经很清楚了。下面来具体解释下上面这张图。

1、四个主要模块和核心功能

ConfigService

提供配置的读取、推送等功能,服务对象是Apollo客户端(client)(最终目的就是把配置数据给到我们自己的微服务对象)

Admin Service

提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)(简单理解成就是就是用来在配置中心管理界面来添加或者修改配置)

Client( 客户端)

Apollo提供的客户端程序,为应用提供配置获取、实时更新等功能。

域名访问 Meta Server 获取 Config Service 服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做负载均衡错误重试

Portal

提供Web界面供用户管理配置。

Portal通过域名访问 Meta Server 获取 Admin Service 服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做 负载均衡错误重试

个人理解这四个模块

ConfigService 和 Client 的配合

从这里面可以看出我们自己的微服务不是直接和ConfigService打交道的,而是跟Client打交道,Client才是真正和ConfigService打交道来获取最新配置信息。

Admin Service 和 Portal

这里分类两个模块就很好理解了,因为管理界面的实现有自己的一套代码,而且管理界面操作的一些权限等信息,只会跟它自己有关系,对于微服务来讲,我只关心有没有配置

这条配置数据,而不会去关心在管理界面上什么用户能够添加配置信息。所以就有Portal对于了两个数据库,一个可以理解是它自己的,存放一些权限等信息,另一部分是和

配置有关的,所以通过 Admin Service 存放在 configDB 中。

2、三个辅助服务发现模块

为了保证上面四个模块的高可用,所以这里需要三个辅助模块配合。

Eureka

用于服务发现和注册Config/AdminService注册实例并定期报心跳。

为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

官方也有解释为什么我们采用Eureka作为服务注册中心,而不是使用传统的zk、etcd呢?我大致总结了一下,有以下几方面的原因:

1)它提供了完整的Service Registry和Service Discovery实现

首先是提供了完整的实现,并且也经受住了Netflix自己的生产环境考验,相对使用起来会比较省心。

2)和Spring Cloud无缝集成

我们的项目本身就使用了Spring Cloud和Spring Boot,同时Spring Cloud还有一套非常完善的开源代码来整合Eureka,所以使用起来非常方便。另外,Eureka还支持在

我们应用自身的容器中启动,也就是说我们的应用启动完之后,既充当了Eureka的角色,同时也是服务的提供者。这样就极大的提高了服务的可用性。这一点是我们选择

Eureka而不是zk、etcd等的主要原因,为了提高配置中心的可用性和降低部署复杂度,我们需要尽可能地减少外部依赖。

3)Open Source

最后一点是开源,由于代码是开源的,所以非常便于我们了解它的实现原理和排查问题。

MetaServer

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

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

相当于一个Eureka Proxy 逻辑角色,和ConfigService住在一起部署。

NginxLB

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

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

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

二、架构剖析

1、Apollo架构V1

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

要点

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

2、Apollo架构V2

为了保证高可用,ConfigService和AdminService都是无状态以集群方式部署的,这个时候就存在一个服务发现问题:Client怎么找到ConfigService?Portal

怎么找到AdminService?为了解决这个问题,Apollo在其架构中引入了Eureka服务注册中心组件,实现微服务间的服务注册和发现,更新后的架构如下图所示:

要点

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

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

3、Apollo架构V3

我们知道Eureka是自带服务发现的Java客户端的,如果Apollo只支持Java客户端接入,不支持其它语言客户端接入的话,那么Client和Portal只需要引入Eureka的Java

客户端,就可以实现服务发现功能。发现目标服务后,通过客户端软负载(SLB,例如Ribbon)就可以路由到目标服务实例。这是一个经典的微服务架构,基于Eureka实现

服务注册发现+客户端Ribbon配合实现软路由,如下图所示:

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

5、Apollo架构V5

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

用户通过域名+NginxLB间接访问MetaServer集群。

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

6、结论

  1. 经过我在第三部分的剖析之后,相信大家对Apollo的微服务架构会有更清晰的认识,作为一个思考题,大家再回头看一下第二部分宋顺给出的架构图,现在是否能够理解?

它和我的架构是如何对应的?提示一下,宋顺的视角是一个从上往下的俯视视角,而我的是一个侧面视角。

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

发现的模块。

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

中的配置,这个是它的架构的一大亮点。。

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

三、可用性考虑

上面设计这么复杂就是为了满足高可用,如果不考虑可用性,那么那么的v1图片就可以满足。我们来下最终的架构图为什么能满足高可用。

很明显这些模块任何一个挂掉,都能满足服务的可以用性。

Apollo架构设计的更多相关文章

  1. 【Apollo】(2)--- Apollo架构设计

    Apollo架构设计 上一篇博客有讲到:[Apollo](1)--- Apollo入门介绍篇 这篇来写Apollo的核心架构设计 一.整体架构 Apollo整体架构图,已由作者宋顺已经给出: 这幅图所 ...

  2. .NET Core/.NET5/.NET6 开源项目汇总6:框架与架构设计(DDD、云原生/微服务/容器/DevOps/CICD等)项目

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...

  3. 浅谈 jQuery 核心架构设计

    jQuery对于大家而言并不陌生,因此关于它是什么以及它的作用,在这里我就不多言了,而本篇文章的目的是想通过对源码简单的分析来讨论 jQuery 的核心架构设计,以及jQuery 是如何利用javas ...

  4. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  5. 解构C#游戏框架uFrame兼谈游戏架构设计

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  6. VICA 架构设计(1)

    本文记录最近完成的一个通用实时通信客户端的架构.   背景 我们公司是做税务相关的软件,有针对大客户 MIS 系统,也有针对中小客户的 SaaS 平台.这些系统虽然都是 B/S 的,但是也需要使用 A ...

  7. 一种简单的CQRS架构设计及其实现

    一.为什么要实践领域驱动? 近一年时间我一直在思考一个问题:"如何设计一个松耦合.高伸缩性.易于维护的架构?".之所以有这样的想法是因为我接触的不少项目都是以数据库脚本来实现业务逻 ...

  8. 基于token的多平台身份认证架构设计

    基于token的多平台身份认证架构设计 1   概述 在存在账号体系的信息系统中,对身份的鉴定是非常重要的事情. 随着移动互联网时代到来,客户端的类型越来越多, 逐渐出现了 一个服务器,N个客户端的格 ...

  9. 架构设计:一种远程调用服务的设计构思(zookeeper的一种应用实践)

    在深入学习zookeeper我想先给大家介绍一个和zookeeper相关的应用实例,我把这个实例命名为远程调用服务.通过对这种应用实例的描述,我们会对zookeeper应用场景会有深入的了解. 远程调 ...

  10. ABP架构设计交流群-上海线下交流会的内容分享(有高清录像视频的链接)

    点这里进入ABP系列文章总目录 ABP架构设计交流群-7月18日上海线下交流会内容分享 因为最近工作特别忙,很久没有更新博客了,真对不起关注我博客和ABP系列文章的朋友! 原计划在7月11日举行的AB ...

随机推荐

  1. 应届生必看!23 个高质量 C++ 项目推荐,校招简历秒加分

    大家好,我是小康. 最近,不少同学私信我,临近毕业忙着找工作,想问有没有推荐的 C++ 项目,既能练手又能让简历更出彩.我也想起自己当年毕业时同样的焦虑,知道作为 C++ 后端开发的求职者,有几个实际 ...

  2. 5.3 Linux Vim三种工作模式

    通过前面的学习我们知道,Linux 系统中所有的内容都以文件的形式进行存储,当在命令行下更改文件内容时,常会用到文本编辑器. 我们首选的文本编辑器是 Vim(至于为什么,可查看<Vi和Vim之间 ...

  3. chapter1 events and probability

    第一章  事件和概率 1.1 Appication: verifying polynomial identities 1.2 Axioms of probability 1.3 Application ...

  4. .NET周刊【11月第3期 2024-11-17】

    国内文章 .NET 9使用Scalar替代Swagger https://www.cnblogs.com/netry/p/18543378/scalar-an-alternative-to-swagg ...

  5. 切换自己为www-data用户

    突发奇想的想把切换为www-data用户去看看会怎么样.然后做了一个尝试 由于我安装了lamp环境,所以有www-data用户,用它可以来执行web php ,以及安全放心的跑cli(避免权限过高执行 ...

  6. VulnHub-Sick0s1.1解法二shellshock漏洞

    免责声明 本博客提供的所有信息仅供学习和研究目的,旨在提高读者的网络安全意识和技术能力.请在合法合规的前提下使用本文中提供的任何技术.方法或工具.如果您选择使用本博客中的任何信息进行非法活动,您将独自 ...

  7. (Redis基础教程之十三) 如何从命令行更改Redis的配置

    介绍 Redis是一个开源的内存中键值数据存储.Redis有几个命令,可让您即时更改Redis服务器的配置设置.本教程将介绍其中一些命令,并说明如何使这些配置更改永久生效. 如何使用本指南 本指南以备 ...

  8. java应用详解

    java应用详解 文档介绍: 1.nio应用(ServerSocketChannel.FileChannel). 2.优化jvm参数提升eclipse运行速度. 3.maven3.0.3安装及入门例子 ...

  9. go get 和 go install 对比

    (一)命令定义和区别 go install 和 go get 都是 Go 语言的工具命令,但它们之间有一些区别. go get:用于从远程代码存储库(如 GitHub)中下载或更新 Go 代码包.它会 ...

  10. Linux内核内存保护机制:aslr和canary

    Linux内核内存保护机制:aslr和canary ASLR ASLR技术,全称为Address space layout randomization(地址空间布局随机化),是现代通用操作系统基本都会 ...