配置中心Apollo入门

Apollo是携程开源的配置中心,社区比较火,当前在生产中使用的用户量也非常大。用户侧的功能和使用,本文就不一一介绍了,这方面的文档比较多。这里结合最近在公司环境中的大规模部署,简要做一些概要总结,重点涉及一些分布式部署中可能遇到的问题。

软件架构

架构

我们先来对架构有一个总体的认识,上图是apollo的模块架构,接下来我们将对图上各模块做逐一功能职责的介绍。

各模块功能

  • ConfigService

    1. 提供配置获取接口
    2. 提供配置推送接口
    3. 服务于Apollo客户端
  • MetaServer

    1. Portal通过域名访问MetaServer获取AdminService的地址列表
    2. Client通过域名访问MetaServer获取ConfigService的地址列表
    3. 相当于一个Eureka Proxy (提供rest-api), 和ConfigService在一起部署(同一个jvm)
  • Eureka

    1. 用于服务发现和注册
    2. Config/AdminService注册实例并定期报心跳
    3. 和ConfigService住在一起部署
  • AdminService

    1. 提供配置管理接口
    2. 提供配置修改发布接口
    3. 服务于管理界面Portal
    4. 吐槽: 这货与ConfigService共享DB, 除了使用DB做消息通道外(原谅)、还做配置中心(靠)
  • Portal

    1. 配置管理界面
    2. 通过MetaServer获取AdminService的服务列表
    3. 使用客户端软负载SLB方式调用AdminService
  • LB

    1. 和域名系统配合,协助Portal访问MetaServer获取AdminService地址列表(也可以配置为客户端负载均衡)
    2. 和域名系统配合,协助Client访问MetaServer获取ConfigService地址列表
    3. 和域名系统配合,协助用户访问Portal进行配置管理
  • Client

    1. 为应用获取配置,支持实时更新
    2. 通过MetaServer获取ConfigService的服务列表
    3. 使用客户端软负载SLB方式调用ConfigService

配置下发流程

为了突出关键内容,下面流程忽略掉了服务发现的步骤;结合架构图,请自行脑补各模块之间怎么基于DB中的内容来找到目标模块。

  1. 用户在Portal上修改配置,并发布;
  2. 基于配置所在的目标环境,Portal调用对应AdminService的接口来操作发布;
  3. AdminService发布配置后,发送ReleaseMessage到其关联的数据库;
  4. ConfigService每秒扫描数据库,一旦发现存在新的消息记录,就通知到消息监听器,由消息监听器通知Client;
  5. Client与ConfigService之间是通过HTTP long-polling来实现长连接的;
  6. 作为一种补偿机制,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的metadata-server多个实例的地址,这样会有什么问题吗?举一个例子,如果meta-server-1是健康的,所以lb-2会将请求路由过来处理。但是meta-server-1上注册的所有admin-server都挂掉了,此时这个请求就必然面临超时的异常。但是,portal-server的作者为我们想到了这一点,进入源码查看,会发现portal-server每次都是直接找到可用的admin-server,而不是找到对应的meta-server就终止。

config-server配置

  • 如前面提到的,当我们在某一个环境有跨数据中心部署的需求时,各个数据中心理论上都有自己的中间件,因此对于应用程序来说,配置都会有差异。因此,两个区域的应用程序理论上都没有跨区域去获取配置的需求。
  • 对于这种情况,config-server、admin-server支持按照区域(cluster)来注册到不同的meta-server。当然,meta-server通config-server一起部署到一个jvm中,因此也是位于不同的cluster中。比如,图中DEV环境的idc-1中,多个meta-server之间相互同步所注册的服务,但是与DEV环境的idc-2中的meta-server之间不会有同步操作。对于客户端来讲,其所位于哪一个idc,就需要访问该idc中对应的meta-server,一般该meta-server都做了多实例部署,通过暴露负载均衡地址的方式来供客户端访问。
  • 为了让idc中的config-server、admin-server只注册到本idc的meta-server,需要在ServerConfig表中添加对应idc的条目,重点是对应的eureka.server.url。同时,需要修改对应的配置文件/opt/settings/server.properties,具体见图上。

使用与抽象

  • 项目或者应用(application)
    代表一个使用配置中心的应用,每个应用会有一个appID,需要在代码中使用到;

  • 环境(environment)
    这里的环境是固定的几个值,即:DEV、UAT、PRO。环境信息决定了portal要将配置信息发送到哪些admin-server中,是由外入里的第一层。

  • 集群(cluster)
    是一种抽象,可以是机房的概念,也可以是一个逻辑集合。不同集群会使用不同的config-server,一个config-server就对应一个集群。

  • 命名空间(namespace)
    对应同一个应用的多个配置文件,一个命名空间对应一个配置文件。命名空间有分类,有的可以继承配置信息,就不需要重复配置数据。
    应用默认会自带application这个namespace,一般对应JAVA的application.yaml。
    namespace支持的格式包括:propertiesxmlymlyamljson
    namespace支持两种权限: private(能被任何应用获取) 和 public(只能被所属的应用获取到)
    namespace支持三种权属关系:私有类型公共类型关联类型(继承类型)

0%