一、架构图解
二、核心模块
-
ConfigService
1)提供配置获取接口
2)提供配置推送接口(服务端使用Spring DeferredResult实现异步化,从而大大增加长连接数量,目前使用的tomcat embed默认配置是最多10000个连接(可以调整),使用了4C8G的虚拟机实测可以支撑10000个连接,所以满足需求(一个应用实例只会发起一个长连接)
3)服务于Apollo客户端
-
AdminService
1)提供配置管理接口
2)提供配置修改发布接口
3)服务于管理界面Portal
-
Client
1)为应用获取配置,支持实时更新
2)通过MetaServer获取ConfiigService的服务列表
3)使用客户端负载SLB方式调用ConfigService
-
Portal
1)配置管理界面
2)通过MetaServer获取AdminService的服务列表
3)使用客户端负载SLB方式调用AdminService
三、辅助服务发现模块
-
Eureka
1)基于Eureka和Spring Cloud Netflix提供服务发现和注册
2)Config/AdminService注册实例并定期报心跳
3)和ConfigService住在一起部署(为什么?为了简化部署)
4)Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳
-
MetaServer
1)Portal通过域名访问MetaServer获取AdminService的地址列表
2)Client通过域名访问MetaServer获取ConfigService的地址列表
3)相当于一个Eureka Proxy(在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口,对Portal和Client而言,永远通过一个Http接口获取Admin Service和Config
4)逻辑角色,和ConfigService住在一起部署且放在同一个JVM进程中
5)MetaServer+Eureka=k8s.service(提供查看endpoint的功能,真实访问通过endpoint)
-
NginxLB
1)和域名系统配合,协助Portal访问MetaServer获取AdminService地址列表
2)和域名系统配合,协助Client访问MetaServer获取ConfigService地址列表
3)和域名系统配合,协助用户访问Portal进行配置管理
四、服务端设计
-
发布后实时推送
1)用户在Portal操作配置发布
2)Portal调用Admin Service的接口操作发布
3)Admin Service发布配置后,发送ReleaseMessage给各个Config Service
4)Config Service收到ReleaseMessage后,通知对应的客户端
-
发送ReleaseMessage的实现方式(通过数据库实现了一个简单的消息队列)
1)Admin Service在配置发布后会往ReleaseMessage表插入一条消息记录,消息内容就是配置发布的AppId+Cluster+Namespace
2)Config Service有一个线程会每秒扫描一次ReleaseMessage表,看看是否有新的消息记录
3)Config Service如果发现有新的消息记录,那么就会通知到所有的消息监听器,如NotificationControllerV2
4)NotificationControllerV2得到配置发布的AppId+Cluster+Namespace后,会通知对应的客户端
-
Config Service通知客户端的实现方式
1)客户端会发起一个Http请求到Config Service的notifications/v2接口
2)NotificationControllerV2不会立即返回结果,而是通过Spring DeferredResult把请求挂起
3)如果在60秒内没有该客户端关心的配置发布,那么会返回Http状态码304给客户端
4)如果有该客户端关心的配置发布,NotificationControllerV2会调用DeferredResult的setResult方法,传入有配置变化的namespace信息,同时该请求会立即返回。客户端从返回的结果中获取到配置变化的namespace后,会立即请求Config Service获取该namespace的最新配置
五、客户端设计
-
客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送
-
客户端还会定时从Apollo配置中心服务端拉取应用的最新配置
1)这是一个fallback机制,为了防止推送机制失效导致配置不更新
2)客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
3)定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟(即:不允许随意发布配置,会被自动更新到线上)
-
客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
-
客户端会把从服务端获取到的配置在本地文件系统缓存一份,在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
-
应用程序从Apollo客户端获取最新的配置、订阅配置更新通知(apollo主动发起的配置变更)
六、监控相关
-
Apollo客户端和服务端目前支持CAT自动打点,所以如果自己公司内部部署了CAT的话,只要引入cat-client后Apollo就会自动启用CAT打点。
-
如果不使用CAT的话,也不用担心,只要不引入cat-client,Apollo是不会启用CAT打点的
七、可用性设计
场景
|
影响
|
降级
|
原因
|
某台config service下线
|
无影响
|
|
Config service无状态,客户端重连其它config service
|
所有config service下线
|
客户端无法读取最新配置,Portal无影响
|
客户端重启时,可以读取本地缓存配置文件
|
|
某台admin service下线
|
无影响
|
|
Admin service无状态,Portal重连其它admin service
|
所有admin service下线
|
客户端无影响,portal无法更新配置
|
|
|
某台portal下线
|
无影响
|
|
Portal域名通过slb绑定多台服务器,重试后指向可用的服务器
|
全部portal下线
|
客户端无影响,portal无法更新配置
|
|
|
某个数据中心下线
|
无影响
|
|
多数据中心部署,数据完全同步,Meta Server/Portal域名通过slb自动切换到其它存活的数据中心
|