Apollo是携程开源的配置中心,社区比较火,当前在生产中使用的用户量也非常大。用户侧的功能和使用,本文就不一一介绍了,这方面的文档比较多。这里结合最近在公司环境中的大规模部署,简要做一些概要总结,重点涉及一些分布式部署中可能遇到的问题。
软件架构
我们先来对架构有一个总体的认识,上图是apollo的模块架构,接下来我们将对图上各模块做逐一功能职责的介绍。
各模块功能
-
ConfigService
- 提供配置获取接口
- 提供配置推送接口
- 服务于Apollo客户端
-
MetaServer
- Portal通过域名访问MetaServer获取AdminService的地址列表
- Client通过域名访问MetaServer获取ConfigService的地址列表
- 相当于一个Eureka Proxy
- 逻辑角色,和ConfigService住在一起部署
-
Eureka
- 用于服务发现和注册
- Config/AdminService注册实例并定期报心跳
- 和ConfigService住在一起部署
-
AdminService
- 提供配置管理接口
- 提供配置修改发布接口
- 服务于管理界面Portal
-
Portal
- 配置管理界面
- 通过MetaServer获取AdminService的服务列表
- 使用客户端软负载SLB方式调用AdminService
-
Nginx LB
- 和域名系统配合,协助Portal访问MetaServer获取AdminService地址列表
- 和域名系统配合,协助Client访问MetaServer获取ConfigService地址列表
- 和域名系统配合,协助用户访问Portal进行配置管理
-
Client
- 为应用获取配置,支持实时更新
- 通过MetaServer获取ConfigService的服务列表
- 使用客户端软负载SLB方式调用ConfigService
配置下发流程
为了突出关键内容,下面流程忽略掉了服务发现的步骤;结合架构图,请自行脑补各模块之间怎么基于DB中的内容来找到目标模块。
- 用户在Portal上修改配置,并发布;
- 基于配置所在的目标环境,Portal调用对应AdminService的接口来操作发布;
- AdminService发布配置后,发送ReleaseMessage到其关联的数据库;
- ConfigService每秒扫描数据库,一旦发现存在新的消息记录,就通知到消息监听器,由消息监听器通知Client;
- Client与ConfigService之间是通过HTTP long-polling来实现长连接的;
- 作为一种补偿机制,Client还定期从ConfigService拉取最新配置(默认每5分钟拉取一次,可以自定义);
服务端口
服务 |
端口 |
config server |
8080 |
admim server |
8090 |
portal server |
8070 |
部署
准备工作
在github上下载apollo对应的release包,主要包含三部分:
- apollo-adminserver
- apollo-configservice (包含ConfigServer、MetaServer和Eureka)
- apollo-portal
除了这些jar包之外,还需要mysql数据库和负载均衡,用来向客户端和用户暴露统一的访问地址。
部署架构
下面是部署两套环境DEV、UAT(每套环境都有两个IDC)的一张架构图,具体如下:
数据流
在前面的章节我们大概讲了配置发布的流程,这里重点结合负载均衡来讲一下(对理解配置有好处)。
portal-server配置
- 首先,用户访问UI的请求通过LB-1进来被送到portal server上处理。因此,LB-1应该暴露8070端口,其upstream为多个portal-server的8070端口。
- portal-server接收发布配置请求之后,需要找到配置所属环境的admin-server来将配置写入到数据库中,并向admin-server发送releaseMessage。为了便于找到各个环境对应的admin-server,portal-server需要去查找对应环境的meta-server,再通过meta-server来查询当前可用的admin-server。各环境与其对应meta-server地址的映射关系,需要我们手动写入到portal-server的配置文件中,具体见架构图。
- 现在问题来了,假设我们在同一个环境中有多个idc,每个idc为了client不跨地域访问,都只将config-server和admin-server注册到本地域的meta-server上,那么,portal-server应该如何路由需要发送到admin-server的请求呢?答案是:随意!因为对于portal-server来讲,admin-server属于哪一个idc都没有关系,只要它能够正确的访问到该环境的数据库,portal-server就敢大胆的将活儿承包给这个老弟做。
- 假设我们在lb-2上代理idc-1和idc-2的metadata-server地址,这样会有什么问题吗?举一个例子,如果meta-server-1是健康的,所以lb-2会将请求路由过来处理。但是meta-server-1上注册的所有admin-server都挂掉了,此时这个请求就必然面临超时的异常。但是,portal-server的作者为我们想到了这一点,进入源码查看,会发现portal-server每次都是直接找到可用的admin-server,而不是找到对应的meta-server就终止。
原文
http://ljchen.net/2019/03/02/配置中心apollo入门/