北冰洋以北 发表于 2024-12-9 07:26:06

Apollo功能及原理详解

前言

公司里面使用的配置中心是携程开源的Apollo,之前我只使用过Nacos,遂记载一放学习过程。
Apollo工作原理

https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225308555.png
模块介绍

上图就是Apollo的总体设计,从下往上挨个分析:

[*]ConfigDB用于存储各种配置
[*]Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端,多实例,必要注册到Eureka中保持心跳检测
[*]Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面),多实例,必要注册到Eureka中保持心跳检测
[*]Eureka提供服务注册和发现,为了简朴起见,目前Eureka在部署时和Config Service是在一个JVM进程中
[*]Meta Server用于封装Eureka的服务发现接口
[*]Client通过域名访问Meta Server获取Confifig Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试
[*]Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试
实行流程


[*]Apollo启动后,Config/Admin Service会主动注册到Eureka服务注册中心,并定期发送保活心跳;
[*]Apollo Client和Portal管理端通过配置的Meta Server的域名地址经由Software Load Balancer(软件负载平衡器)举行负载平衡后分配到某一个Meta Server;
[*]Meta Server从Eureka获取Config Service和Admin Service的服务信息,相称于是一个Eureka Client;
[*]Meta Server获取Config Service和Admin Service(IP+Port)失败后会举行重试;
[*]获取到正确的Config Service和Admin Service的服务信息后,Apollo Client通过Config Service为应用提供配置获取、实时更新等功能;Apollo Portal管理端通过Admin Service提供配置新增、修改、发布等功能。
基本概念


[*]application (应用)
现实使用配置的应用,Apollo客户端在运行时必要知道当前应用是谁,从而可以去获取对应的配置。关键字:appId
[*]environment (情况)
配置对应的情况,Apollo客户端在运行时必要知道当前应用处于哪个情况,从而可以去获取应用的配置。关键字:env
[*]cluster (集群)
一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。关键字:cluster
[*]namespace (定名空间)
一个应用下不同配置的分组,可以简朴地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等。关键字:namespaces
关系图如下所示:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225732621.png
项目管理

部门管理

apollo 默认部门有两个。要增长自己的部门,可在体系参数中修改,进入体系参数,输入key查询已存在的部门设置:organizations
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225750835.png
修改value值来添加新部门,下面添加一个微服务部门:
[{"orgId":"TEST1","orgName":"样例部门1"},{"orgId":"TEST2","orgName":"样例部门2"},{"orgId":"micro_service","orgName":"微服务部门"}]创建项目


[*]打开apollo主页,点击创建应用:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225326931.png
[*]输入相干信息,包括部门、应用AppId、应用名称和应用负责人
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225338725.png
[*]将项目授予用户管理服务的权限,点击授权
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225350797.png
[*]使用zhangsan账号登岸,就可以看到能管理的应用了
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225812682.png
删除项目

如果要删除整个项目,点击右上角的管理员工具,再点击删除应用、集群。
起首查出压迫删除的项目是,然后点击删除应用:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225402187.png
配置管理

发布配置


[*]通过表格模式添加:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225413296.png
[*]通过文本模式批量添加:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225424815.png
[*]最后点击右上角发布按钮发布配置。
修改配置

找到必要修改的配置项,举行修改
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225436394.png
修改完举行提交,之后在重新发布配置。
删除配置

与上面一样,删除配置后重新发布。
设置私有Namespace

Namespace同样也可以当作一个配置文件,以rocketmq配置为例,添加“spring-rocketmq” Namespace配置rocketmq相干信息。

[*]创建定名空间
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225448568.png
[*]添加配置项
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225501176.png
[*]举行发布。
设置公共Namespace

在项目开发中,有一些配置可能是通用的,我们可以通过把这些通用的配置放到公共的Namespace中,如许其他项目要使用时可以直接添加必要的Namespace。
添加配置


[*]新建一个common-template项目
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225515034.png
[*]添加公共Namespace:spring-boot-http
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225528044.png
[*]添加配置项并发布
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225542967.png
关联公共Namespcae

创建完公共定名空间之后,必要将项目举行关联才气使用。
打开之前创建的account-service项目,点击左侧的添加Namespace,再添加Namespace:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225558852.png
若是当前项目必要的配置与公共配置中提供的不一样,也可以根据需求覆盖定制配置。
读取配置

读取某个集群的配置,必要启动应用时在VM option指定详细的应用、情况和集群。
-Dapp.id=应用名称
-Denv=情况名称
-Dapollo.cluster=集群名称
-D情况_meta=meta地址
详细实例如下:
‐Dapp.id=account‐service
‐Denv=DEV
‐Dapollo.cluster=SHAJQ
‐Dapollo.meta=http://localhost:8080配置发布原理分析

在配置中心中,一个重要的功能就是配置发布后实时推送到客户端。下面我们扼要看一下这块是怎么设计实现的:
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225614649.png

[*]用户在Portal操作配置发布
[*]Portal调用Admin Service的接口操作发布
[*]Admin Service发布配置后,发送ReleaseMessage给各个Config Service
[*]Config Service收到ReleaseMessage后,通知对应的客户端
源码分析

发送ReleaseMessage

Admin Service在配置发布后,必要通知所有的Config Service有配置发布,从而Config Service可以通知对应的客户端来拉取最新的配置。
从概念上来看,这是一个典型的消息使用场景,Admin Service作为producer(生产者)发出消息,各个Config Service作为consumer(消费者)消费消息。通过一个消息队列组件(Message Queue)就能很好的实现Admin Service和Config Service的解耦。
在实现上,考虑到Apollo的现实使用场景,以及为了尽可能淘汰外部依赖,Apollo没有接纳外部的消息中间件,而是通过数据库实现了一个简朴的消息队列。
详细实现如下:

[*]Admin Service在配置发布后会往ReleaseMessage表插入一条消息记载,消息内容就是配置发布的AppId+Cluster+Namespace:
消息发送类:DatabaseMessageSende
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225627572.png
[*]Config Service有一个线程会每秒扫描一次ReleaseMessage表,看看是否有新的消息记载。
消息扫描类:ReleaseMessageScanner
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225642427.png
[*]Config Service如果发现有新的消息记载,那么就会通知到所有的消息监听器
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225655228.png
[*]有一个类叫NotifificationControllerV2,当它得到配置发布的AppId+Cluster+Namespace后,会通知对应的客户端。

[*]客户端会发起一个Http请求到Config Service的 notifications/v2 接口NotificationControllerV2
https://blog-lemon.oss-cn-shanghai.aliyuncs.com/blog/20241208225711744.png
[*]NotificationControllerV2不会立即返回效果,而是把请求挂起。考虑到会有数万客户端向服务端发起长连,因此在服务端使用了async servlet(Spring DeferredResult)来服务Http Long Polling请求。
[*]如果在60秒内没有该客户端关心的配置发布,那么会返回Http状态码304给客户端。
[*]如果有该客户端关心的配置发布,NotificationControllerV2会调用DeferredResult的setResult方法,传入有配置变革的namespace信息,同时该请求会立即返回。客户端从返回的效果中获取到配置变革的namespace 后,会立即请求Config Service获取该namespace的最新配置。
[*]除此之外,客户端还会定时从Apollo配置中心服务端拉取应用的最新配置,防止推送机制失效导致配置不更新,提升了可用性,默认定时拉取频率是5分钟。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Apollo功能及原理详解