Apollo 配置中心:分布式部署

Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

服务端架构

服务端架构图

上图简要描述了 Apollo 的总体设计:

  • Config Service 提供配置的读取、推送等功能,服务对象是 Apollo 客户端
  • Admin Service 提供配置的修改、发布等功能,服务对象是 Apollo Portal(管理界面)
  • Config Service 和 Admin Service 在生产环境都是多实例、无状态部署,所以需要将自己注册到 Eureka 中并保持心跳
  • 在 Eureka 之上有一层 Meta Server 用于封装 Eureka 的服务发现接口
  • Client 通过域名访问 Meta Server 获取 Config Service 服务列表(IP+Port),而后直接通过 IP+Port 访问服务,同时在 Client 侧会做 load balance、错误重试
  • Portal 通过域名访问 Meta Server 获取 Admin Service 服务列表 IP+Port,而后直接通过 IP+Port 访问服务,同时在 Portal 侧会做 load balance、错误重试

部署策略

部署策略图

上图描述了 Apollo 的部署策略:

  • PortalDB 主要保存权限、支持的环境等数据,Apollo Portal 环境只需要部署一套,管理所有环境(DEV、FAT、UAT、PRO)
  • ConfigDB 保存应用相关的配置数据,每个环境需要独立的 ConfigDB 数据库
  • 为保证稳定性,PortalDB 和 ConfigDB 需要支持 Master-Slave 模式
  • 为简化部署,实际上会把 Config Service、Eureka 和 Meta Server 部署在同一个 JVM 进程中,Admin Service 部署在另一个 JVM 线程中
  • Meta Server、Eureka 、Config Service 和 Admin Service 在生产环境可部署在两个机房,实现双活

客户端架构

客户端架构图

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

  • 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送
  • 客户端会定时从 Apollo 配置中心服务端拉取应用的最新配置(防止推送机制失效导致配置不更新)
  • 客户端从 Apollo 配置中心服务端获取到应用的最新配置后,会保存在内存中
  • 客户端会把从服务端获取到的配置在本地文件系统缓存一份,在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
  • 应用程序从 Apollo 客户端获取最新的配置、订阅配置更新通知

分布式部署

通过以上的介绍,可以看出 Apollo 的整体架构并不简单,但其实也不用担心,在部署上也并没那么复杂。接下来主要介绍 Apollo 的分布式部署,之后的文章中会介绍如何在 Java、.NET 客户端中使用,部署将使用 Docker 的方式,所以读者最好有一定的 Docker 基础。

有 Apollo 用户已经提供了现成的 Dcoker 镜像,我们可以直接使用。不过这里还是将通过编译源代码的方式来介绍,目的是从最原始操作开始,了解整个过程的实现。

环境要求

  • JDK 1.8+ (安装后,修改 Path 环境变量)
  • Maven 3.5+ (安装后,修改 Path 环境变量,建议修改 Maven 源地址,加快下载速度)
  • MySQL 5.6.5+
  • Docker

JDK 和 Maven 只在编译 Apollo 源代码时使用,实际使用 Docker 部署并不需要。

创建数据库

从部署策略图中可以看出,搭建 Apollo 环境需要使用到 PortalDB、ConfigDB 两个数据库,这两个数据库的初始脚本官方源码中已提供:

数据库脚本

我们需要在自己的数据库上执行以上两个文件的脚本,这里将搭建一个基于 PRO 的分布式环境( 如果需要支持多个环境,需要在对应环境的数据库上建 ConfigDB,服务启动改成对应环境的数据库连接,更多请参考 调整ApolloPortalDB配置调整ApolloConfigDB配置 ),如下:

数据库

构建 Docker 镜像

  1. 下载最新 apollo master 分支 代码(当前是 1.5.0-SNAPSHOT),网上很多介绍都需要修改源代码后再进行编译,这个版本已有哥们提交了 Merge Request ,使在 Docker 部署上更简化了。如有特殊需要,也可自行修改源码

  2. 下载完成后在根目录下执行 .\scripts\build.bat(我是在 windows 进行编译的),编译成功后在 apollo-adminserviceapollo-configserviceapollo-portal 下的 target 目录会生成对应压缩包 pollo-configservice-1.5.0-SNAPSHOT-github.zipapollo-adminservice-1.5.0-SNAPSHOT-github.zipapollo-portal-1.5.0-SNAPSHOT-github.zip,这个几个文件就是我们在构建 Docker 镜像需要的

  3. Apollo源码中已经提供了构建 Docker 镜像的 Dockerfile 文件,apollo-configservice\src\main\docker\Dockfileapollo-adminservice\src\main\docker\Dockfileapollo-portal\src\main\docker\Dockfile 可以直接使用,最终如下:

    image.png
  4. 分别构建 Docker 镜像,然后可以通过 docker push 推送到自己的 Docker 仓库,比如 我的仓库 ,或者在要部署是机器上生成 Docker 镜像直接使用,最终得到 apollo-configserviceapollo-adminserviceapollo-portal 3个镜像。

镜像

编写 docker-compose

apollo-configservice && apollo-adminservice:

version: '3'
services:
  apollo-configservice:
    image: apollo-configservice:latest # 镜像地址,这里使用的是直接在当前主机上构建的镜像
    ports:
      - "8080:8080"
    volumes:
      # 日志挂载
      - /usr/local/apollo/servers/server2/logs/apollo-configservice:/opt/logs
    environment:
      # 可通过 SERVER_PORT 指定默认启动端口,ports 也需要对应修改
      # SERVER_PORT: 8080
      # 指定 homePageUrl 为当前宿主的 apollo-configservice 地址,不然会出现无法访问
      JAVA_OPTS: "-Deureka.instance.homePageUrl=http://${当前主机IP}:8080"
      # 数据库连接地址
      DS_URL: "jdbc:mysql://${数据库IP}:${数据库Port}/ApolloConfigDB?characterEncoding=utf8"
      # 数据库用户名
      DS_USERNAME: "apollo"
      # 数据库密码 
      DS_PASSWORD: "123456"
      
  apollo-adminservice:
    image: apollo-adminservice:latest # 镜像地址,这里使用的是直接在当前主机上构建的镜像
    ports:
      - "8090:8090"
    volumes:
      # 日志挂载
      - /usr/local/apollo/servers/server2/logs/apollo-adminservice:/opt/logs
    environment:
      # 指定 homePageUrl 为当前宿主的 apollo-adminservice 地址,不然会出现无法访问
      JAVA_OPTS: "-Deureka.instance.homePageUrl=http://${当前主机IP}:8090"
      # 数据库连接地址
      DS_URL: "jdbc:mysql://${数据库IP}:${数据库Port}/ApolloConfigDB?characterEncoding=utf8"
      # 数据库用户名
      DS_USERNAME: "apollo"
      # 数据库密码 
      DS_PASSWORD: "123456"
    depends_on:
      - apollo-configservice

apollo-portal:

version: '3'
services:
  apollo-portal:
    image: apollo-portal:latest # 镜像地址,这里使用的是直接在当前主机上构建的镜像
    container_name: apollo-portal
    ports:
      - "8070:8070"
    volumes:
      # 日志挂载
      - /usr/local/apollo/servers/server1/logs/apollo-portal:/opt/logs  
    environment:
      # 数据库连接地址
      DS_URL: "jdbc:mysql://${数据库IP}:${数据库Port}/ApolloPortalDB?characterEncoding=utf8" 
      # 数据库用户名
      DS_USERNAME: "apollo"
      # 数据库密码      
      DS_PASSWORD: "123456"
      # META_SERVER 地址,如 http://192.168.100.234:8080,http://192.168.100.234:8081(多个可用,分隔,建议使用 LB 域名),
      PRO_META: "http://${实例1的 apollo-configservice 地址},http://${实例2的 apollo-configservice 地址}"

初始数据库数据修改

ApolloPortalDB 库的 ServerConfig 表 apollo.portal.envsconfigView.memberOnly.envs 值修改为:pro;(因为这里我们搭建的是 PRO 的分布式环境)

ApolloConfigDB 库的 ServerConfig 表 eureka.service.url 值修改为:http://${实例1的 apollo-configservice 地址}/eureka/,http://${实例2的 apollo-configservice 地址}/eureka/

启动服务

这里将在同一个机器上启动 1 个 apollo-portal 实例(端口 8070),2 个 apollo-configservice(端口 8080、8081)和 2 个 apollo-adminservice(端口 8090、8091)。

注意:启动的过程会比较慢,一般会在 100~200s 左右

eureka 服务注册

通过访问 http://${apollo-portal 服务IP}:8070 ,输入默认用户名密码 apollo/admin 登录:(当前的测试脚本提供一个默认的测试项目,新版本的 sql 脚本可能没有 SampleApp)

Apollo 管理界面

通过 管理员工具 => 系统信息 可查看当前环境信息:

系统信息

可以看出 Config Services 和 Admin Services 都是两个实例,我们可以模拟 kill 其中一台,服务依然是可以正常使用的。

接下来就可以创建应用,添加配置信息,提供给客户端使用,具体客户端如何使用后续将会继续介绍。

参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容