Apollo快速了解

191 阅读13分钟

说明:内容仅供学习参考,想深入了解还需要自行阅读官方文档、代码;

本文主要介绍了:

1、 apollo是什么,为什么用Apollo,怎么用以及一些规范问题

2、 简单说明Apollo架构设计 、运行机制

大部分内容引用自官方文档

1. 简介

1.1、是什么:

官方:Apollo是一个配置管理中心,由携程开源,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景

简单:携程框架部门开源的一个配置中心服务,它提供了一种简单的、统一的配置管理接口

1.2、使用场景:

开关、参数的配置、下游地址、中间件地址等

1.3、为什么用它:

首先看下开源配置中心对比:Apollo > Disconf > Spring Cloud Config > Netflix Archaius

结论: Apollo功能丰富,灵活的运行环境分离、多语言客户端等

1.3、为什么用它:

首先看下开源配置中心对比:Apollo > Disconf > Spring Cloud Config > Netflix Archaius

结论: Apollo功能丰富,灵活的运行环境分离、多语言客户端等

1.4、Apollo 核心优势:

按需加载配置:应用启动时加载必要配置,运行中可按需更新。

实时更新:修改后的配置能够在不重启服务的前提下实时生效。

版本回退:提供配置历史版本管理,一键回滚至之前的配置版本。

权限控制:细粒度的权限控制能力,确保配置的安全性

2. 架构设计

2.1 总体设计

1. 基础模型

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

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

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

2. 模块介绍

1. Config Service

● 提供配置获取接口

● 提供配置更新推送接口(基于Http long polling)

○ 服务端使用Spring DeferredResult实现异步化,从而大大增加长连接数量

○ 目前使用的tomcat embed默认配置是最多10000个连接(可以调整),使用了4C8G的虚拟机实测可以支撑10000个连接,所以满足需求(一个应用实例只会发起一个长连接)。

● 接口服务对象为Apollo客户端(应用)

2. Admin Service

● 提供配置管理接口

● 提供配置修改、发布等接口

● 接口服务对象为Portal

3. Meta Server

● Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port)

● Client通过域名访问Meta Server获取Config Service服务列表(IP+Port)

● Meta Server从Eureka获取Config Service和Admin Service的服务信息,相当于是一个Eureka Client

● 增设一个Meta Server的角色主要是为了封装服务发现的细节,对Portal和Client而言,永远通过一个Http接口获取Admin Service和Config Service的服务信息,而不需要关心背后实际的服务注册和发现组件

● Meta Server只是一个逻辑角色,在部署时和Config Service是在一个JVM进程中的,所以IP、端口和Config Service一致

4. Eureka

● 基于Eureka和Spring Cloud Netflix提供服务注册和发现

● Config Service和Admin Service会向Eureka注册服务,并保持心跳

● 为了简单起见,目前Eureka在部署时和Config Service是在一个JVM进程中的(通过Spring Cloud Netflix)

5. Portal

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

● 通过Meta Server获取Admin Service服务列表(IP+Port),通过IP+Port访问服务

● 在Portal侧做load balance、错误重试

6. Client

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

● 通过Meta Server获取Config Service服务列表(IP+Port),通过IP+Port访问服务

● 在Client侧做load balance、错误重试

3、几个架构设计上的问题:

1、为什么引入Eureka

● 完善的注册发现能力

● Spring Cloud生态,接入友好

● 降低部署成本,减少依赖

2、ConfigService 和 AdminService 访问的都是同一个DB, 为啥要分两个服务

从几个架构设计原则上考虑:

● 单一指责原则

○ ConfigService:负责推送配置信息给客户端应用

○ AdminService:负责配置的管理,如配置变更、发布、权限控制等后台管理任务

● 可伸缩性

○ 不同的伸缩需求: ConfigService 通常面对巨大的读取负载,需要能够水平扩展以响应大量的配置读取请求。而 AdminService 应对的是配置变更等写入操作,其负载相对较低,伸缩需求不同

○ 资源优化: 独立服务可以根据各自的负载特征分别优化资源分配和调优,例如,为 ConfigService 分配更多的资源来优化读取性能。

● 高可用与故障隔离

○ 故障隔离: 如果将 Config Service 和 Admin Service 合并,任何导致服务失败的错误都可能同时影响到配置的提供和管理。分离后,即使 Admin Service 出现问题,也不会影响 Config Service 的配置分发功能。

○ 部署灵活性: 各个服务可以独立部署,这样不仅可以降低单个服务的复杂性,还可以单独升级和维护各个服务,而不会相互干扰

总结:提供更稳定、高效的、便于扩展的服务

3、Admin Service 和 Portal 为啥分离呢

在 Apollo 的设计中,有不同的 DEV、FAT、UAT、PROD 环境,会部署在不同的网络环境下,进行隔离。

每个环境会部署一套 Admin Service + Config Service。

而 Portal 通过调用不同环境部署的 Admin Service 提供的 API 接口,进行不同环境的配置管理。同时权限管理、开放平台 API 都是由 Portal 统一实现来提供的

2.2 服务端设计

1、配置推送设计

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

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

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

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

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

1、 发送ReleaseMessage的实现

Admin Service在配置发布后,需要通知所有的Config Service有配置发布,从而Config Service可以通知对应的客户端来拉取最新的配置。第一印象:可以通过消息解偶实现 。

Apollo的实现:通过数据库实现了一个简单的消息队列 ,示意图如下:

(这里用数据库实现的主要原因是为了减少外部依赖)

实现方式如下:

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、ConfigService通知客户端的实现

上面提到NotificationControllerV2是如何得知有配置发布的,那NotificationControllerV2在得知有配置发布后是如何通知到客户端的呢?

实现方式如下:

1、客户端会发起一个Http请求到ConfigService的notifications/v2接口,也就是NotificationControllerV2,参见RemoteConfigLongPollService

2、NotificationControllerV2不会立即返回结果,而是通过DeferredResult (Spring Framework 6.1.3 API)把请求挂起

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

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

2.3 客户端设计

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

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

2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。这是一个fallback机制,为了防止推送机制失效导致配置不更新

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

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

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

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

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

3. 运行机制

本地运行机制

加入模块之间的依赖:

4. 扩展阅读

1、 Apollo 开发指南:

www.apolloconfig.com/#/zh/develo…

2、 Apollo源码:

github.sheincorp.cn/apolloconfi…

3、 开源配置中心对比:

github.com/apolloconfi…

4、 芋道源码分析

www.iocoder.cn/categories/…

5、 Apollo架构

mp.weixin.qq.com/s/-hUaQPzfs…

6、 SpringBoot 接入Apollo

www.apolloconfig.com/#/zh/usage/…

www.iocoder.cn/Spring-Boot…

7、 本地运行搭建

www.apolloconfig.com/#/zh/develo…

www.iocoder.cn/Apollo/buil…

5.总结

本次分享内容主要是:

1、 介绍了Apollo怎么使用、它跟其它配置中心的优势

2、 简单说了各个模块的作用,及模块间如何交互

3、 说了一些常见的一些问题及一些日常使用规范

4、 简单说明Apollo的架构及运行机制