Apollo配置中心

TOC

Apollo简介

Apollo是什么?

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

官网地址:https://www.apolloconfig.com/#/

Apollo分布式架构

Apollo一共有四大组件:

  • Portal:Web管理界面
  • AdminService:管理服务,供Portal服务调用
  • ConfigService:配置服务,供客户端调用
  • 数据库:分为PortalDB和ConfigDB,分别存储管理端数据和服务数据

部署服务的大致网络架构图如下图所示:
apollo

各服务作用详解

1.Portal(配置管理后台)

  • 定位:Apollo 的管理界面(UI),供开发、运维人员操作。
  • 主要功能
    • 创建项目、配置环境、维护权限。
    • 管理配置项(增删改查)。
    • 配置发布(灰度发布、回滚、版本管理)。
  • 数据库:连接ApolloPortalDB(全局唯一),不直接接触配置数据。
  • 交互方式:通过调用各环境的AdminService API来完成配置修改。

2.AdminService(配置管理服务)

  • 定位:Portal 的后端代理层,专门负责处理配置修改和发布。
  • 主要功能
    • 接收Portal发来的配置修改请求。
    • 写入ApolloConfigDB(该环境独立的配置数据库)。
    • 推送配置变更通知给 ConfigService(保证客户端能快速感知变化)。
  • 数据库:连接该环境的 ApolloConfigDB。
  • 部署建议:流量较小,可以和 ConfigService 部署在同一个进程,也可以单独部署。

3.ConfigService(配置读取服务)

  • 定位:客户端应用的配置获取入口。
  • 主要功能
    • 客户端启动时从 ConfigService 拉取配置。
    • 支持长轮询(通知机制),配置更新后,客户端能在秒级感知到变化。
    • 从ApolloConfigDB中读取配置并缓存,提高读取性能。
  • 数据库:连接该环境的ApolloConfigDB
  • 部署建议
    • 高可用部署(因为所有应用都会频繁访问)。
    • 需要负载均衡(Nginx、K8s Service 等)。

4.数据库

  • ApolloPortalDB(唯一,全局共享)
    • 存储 Portal 自身的元信息,如环境配置、组织架构、用户权限等。
  • ApolloConfigDB(每个环境一套,隔离部署)
    • 存储实际的应用配置信息。
    • 每个环境独立,互不干扰。
    • 配合 AdminService + ConfigService 使用。

Apollo安装部署

★准备工作★

数据库sql文件下载
ApolloPortalDB库:apolloportaldb.sql
ApolloConfigDB库:apolloconfigdb.sql

服务安装包下载
打包好的release版本安装包:https://github.com/apolloconfig/apollo/releases
需要对应版本的链接:https://github.com/apolloconfig/apollo/releases/tag/v版本号

其他操作
1.需要安装1.8+的JDK环境。
2.需要部署好MySQL服务。
3.打通服务之间的内部网络。

安装好JDK环境

java version "1.8.0_451"
Java(TM) SE Runtime Environment (build 1.8.0_451-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.451-b10, mixed mode)

如需运行在 Java 1.7 运行时环境,请使用 1.x 版本的 apollo 客户端,如 1.9.1

部署准备MySQL数据

MySQL数据库版本要求:5.6.5+
1.需要导入两个库的数据,分别是ApolloPortalDB和ApolloConfigDB,先下载sql文件再导入。

# 导入ApolloPortalDB库数据
mysql -h 127.0.0.1 -P 3306 -uroot -p'admin123456' --default-character-set=utf8 < apolloportaldb.sql
# 导入ApolloConfigDB库数据
mysql -h 127.0.0.1 -P 3306 -uroot -p'admin123456' --default-character-set=utf8 < apolloconfigdb.sql

2.通过执行以下sql语句来验证ApolloPortalDB库数据

mysql> select `Id`, `Key`, `Value`, `Comment` from `ApolloPortalDB`.`ServerConfig` limit 1;
+----+--------------------+-------+--------------------------+
| Id | Key                | Value | Comment                  |
+----+--------------------+-------+--------------------------+
|  1 | apollo.portal.envs | dev   | 可支持的环境列表            |
+----+--------------------+-------+--------------------------+
1 row in set (0.00 sec)

3.通过执行以下sql语句来验证ApolloConfigDB库数据

mysql> select `Id`, `Key`, `Value` from `ApolloConfigDB`.`ServerConfig` limit 1;
+----+--------------------+-------------------------------+
| Id | Key                | Value                         |
+----+--------------------+-------------------------------+
|  1 | eureka.service.url | http://127.0.0.1:8080/eureka/ |
+----+--------------------+-------------------------------+
1 row in set (0.00 sec)

4.调整服务端配置
apollo.portal.envsconfigView.memberOnly.envs,还有eureka.service.url配置务必要按照自己部署的环境进行修改。
我们可以修改数据的apolloconfigdb库下的serverconfig表修改eureka.service.url配置。

UPDATE `apolloconfigdb`.`serverconfig` SET `Value` = 'http://192.168.1.101:8080/eureka/' WHERE `Key` = 'eureka.service.url';

下载各个服务安装包

一个三个安装包名字类似:apollo-configservice-x.x.x-github.zipapollo-adminservice-x.x.x-github.zipapollo-portal-x.x.x-github.zip
x.x.x为版本号,根据版本的的不一样,名字也会有所变化。

部署apollo-configservice服务

1.解压安装包

$ tree apollo-configservice-2.4.0-github
apollo-configservice-2.4.0-github
├── apollo-configservice-2.4.0-sources.jar
├── apollo-configservice-2.4.0.jar
├── apollo-configservice.conf
├── config
│   ├── application-github.properties
│   └── application.properties
└── scripts
    ├── shutdown.sh
    └── startup.sh

3 directories, 7 files

2.修改配置文件,连接数据库,配置文件在config/application-github.properties

# config/application-github.properties
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = admin123456

3.启动服务,加上忽略网卡以及暴露服务地址参数

java -server -Xms6144m -Xmx6144m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=384m -XX:NewSize=4096m -XX:MaxNewSize=4096m -XX:SurvivorRatio=18 \
     -Dspring.cloud.inetutils.ignoredInterfaces[0]=docker0 \
	 -Dspring.cloud.inetutils.ignoredInterfaces[1]=veth.* \
	 -Deureka.instance.homePageUrl=http://192.168.1.101:8080 \
	 -Deureka.instance.preferIpAddress=false \
	 -jar apollo-configservice-2.4.0.jar

部署apollo-adminservice服务

1.解压安装包

$ tree apollo-adminservice-2.4.0-github
apollo-adminservice-2.4.0-github
├── apollo-adminservice-2.4.0-sources.jar
├── apollo-adminservice-2.4.0.jar
├── apollo-adminservice.conf
├── config
│   ├── application-github.properties
│   └── application.properties
└── scripts
    ├── shutdown.sh
    └── startup.sh

3 directories, 7 files

2.修改配置文件,连接数据库,配置文件在config/application-github.properties

# config/application-github.properties
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = root
spring.datasource.password = admin123456

3.启动服务,加上忽略网卡以及暴露服务地址参数

java -server -Xms6144m -Xmx6144m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=384m -XX:NewSize=4096m -XX:MaxNewSize=4096m -XX:SurvivorRatio=18 \
     -Dspring.cloud.inetutils.ignoredInterfaces[0]=docker0 \
	 -Dspring.cloud.inetutils.ignoredInterfaces[1]=veth.* \
	 -Deureka.instance.homePageUrl=http://192.168.1.101:8090 \
	 -Deureka.instance.preferIpAddress=false \
	 -jar apollo-adminservice-2.4.0.jar

部署apollo-portal服务

$ tree apollo-portal-2.4.0-github
apollo-portal-2.4.0-github
├── apollo-portal-2.4.0-sources.jar
├── apollo-portal-2.4.0.jar
├── apollo-portal.conf
├── config
│   ├── apollo-env.properties
│   ├── application-github.properties
│   └── application.properties
└── scripts
    ├── shutdown.sh
    └── startup.sh

3 directories, 8 files

修改配置文件,连接数据库

# config/application-github.properties
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloPortalDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = someuser
spring.datasource.password = somepwd

配置各环境Meta Service列表,配置文件在config/apollo-env.properties

# config/apollo-env.properties
dev.meta=http://192.168.1.101:8080

启动服务

java -server -Xms4096m -Xmx4096m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=384m -XX:NewSize=1536m -XX:MaxNewSize=1536m -XX:SurvivorRatio=22 \
    -jar apollo-portal-2.4.0.jar

启动参数解析

configservice和adminservice服务配置

忽略某些网卡
会把docker0veth开头的网卡在注册到Eureka时忽略掉。

# 使用JVM命令参数
-Dspring.cloud.inetutils.ignoredInterfaces[0]=docker0
-Dspring.cloud.inetutils.ignoredInterfaces[1]=veth.*
# 使用环境变量配置
SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[0]=docker0 SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[1]=veth.*

指定要注册的IP
configservice和adminservice需要分别进行配置,配置URL就不需要配置IP了。

# 使用JVM命令参数
-Deureka.instance.ip-address=apollo-configservice地址
-Deureka.instance.ip-address=apollo-adminservice地址
# 使用环境变量配置
EUREKA_INSTANCE_IP_ADDRESS=apollo-configservice地址
EUREKA_INSTANCE_IP_ADDRESS=apollo-adminservice地址

指定要注册的URL
configservice和adminservice需要分别进行配置。

# 使用JVM命令参数
-Deureka.instance.homePageUrl=http://apollo-configservice地址
-Deureka.instance.preferIpAddress=false
-Deureka.instance.homePageUrl=http://apollo-adminservice地址
-Deureka.instance.preferIpAddress=false
# 使用环境变量配置
EUREKA_INSTANCE_HOME_PAGE_URL=http://apollo-configservice地址
EUREKA_INSTANCE_PREFER_IP_ADDRESS=false
EUREKA_INSTANCE_HOME_PAGE_URL=http://apollo-adminservice地址
EUREKA_INSTANCE_PREFER_IP_ADDRESS=false

portal服务配置

Meta Service环境列表
Apollo目前支持以下环境:

  • DEV:开发环境
  • FAT:测试环境,相当于alpha环境(功能测试)
  • UAT:集成环境,相当于beta环境(回归测试)
  • PRO:生产环境
    配置文件和环境变量选择一个进行配置即可。
# 配置文件中配置
dev.meta=http://dev环境apollo-configservice地址
fat.meta=http://fat环境apollo-configservice地址
uat.meta=http://uat环境apollo-configservice地址
pro.meta=http://pro环境apollo-configservice地址
# 使用环境变量配置
DEV_META=http://dev环境apollo-configservice地址
FAT_META=http://fat环境apollo-configservice地址
UAT_META=http://uat环境apollo-configservice地址
PRO_META=http://pro环境apollo-configservice地址

测试阶段

管理端操作

访问portal服务地址,我的地址是http://127.0.0.1:8070,如下图所示:
apollo
默认用户名是:apollo,密码是:admin
登录成功之后界面如下图所示:
apollo
我们可以查看系统信息,如下图所示:
apollo

客户端操作

客户端,比如代码应用程序进行访问需要访问apollo-configservice服务的api地址,所以需要让服务能够访问apollo-configservice的服务地址。比如:
获取某应用的配置:

curl -X GET -l http://{apollo-configservice-host}:{port}/configs/{appId}/{clusterName}/{namespaceName}

docker进行部署

docker-compose.yaml文件如下:

services:
  apollo-mysql:
    image: mysql:8.0.40
    container_name: apollo-mysql
    restart: unless-stopped
    ports:
      - 3306:3306
    command:
      - --default-authentication-plugin=caching_sha2_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
      - --explicit_defaults_for_timestamp=true
      - --lower_case_table_names=1
      - --max_allowed_packet=128M
    environment:
      - "TZ=Asia/Shanghai"
      - "MYSQL_ROOT_PASSWORD=WC85roj5IfwOhIEK"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
      interval: 5s
      timeout: 2s
      retries: 5
      start_period: 20s

  apollo-configservice:
    container_name: apollo-configservice
    image: apolloconfig/apollo-configservice:2.4.0
    restart: always
    environment:
    - SPRING_DATASOURCE_URL=jdbc:mysql://apollo-mysql:3306/ApolloConfigDB?characterEncoding=utf8
    - SPRING_DATASOURCE_USERNAME=root
    - SPRING_DATASOURCE_PASSWORD=WC85roj5IfwOhIEK
    # - EUREKA_INSTANCE_IP_ADDRESS=0.0.0.0
    - EUREKA_INSTANCE_HOME_PAGE_URL=http://apollo-configservice:8080
    - EUREKA_INSTANCE_PREFER_IP_ADDRESS=false
    - SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[0]=docker0
    - SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[1]=veth.*
    volumes:
    - ./logs/configservice:/opt/logs
    healthcheck:
      test: ["CMD", "curl" ,"localhost:8080/health"]
      interval: 5s
      timeout: 1s
      retries: 10
    depends_on:
      apollo-mysql:
        condition: service_healthy

  apollo-adminservice:
    container_name: apollo-adminservice
    image: apolloconfig/apollo-adminservice:2.4.0
    restart: always
    environment:
    - SPRING_DATASOURCE_URL=jdbc:mysql://apollo-mysql:3306/ApolloConfigDB?characterEncoding=utf8
    - SPRING_DATASOURCE_USERNAME=root
    - SPRING_DATASOURCE_PASSWORD=WC85roj5IfwOhIEK
    - EUREKA_INSTANCE_HOME_PAGE_URL=http://apollo-adminservice:8090
    - EUREKA_INSTANCE_PREFER_IP_ADDRESS=false
    - SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[0]=docker0
    - SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[1]=veth.*
    volumes:
    - ./logs/adminservice:/opt/logs
    healthcheck:
      test: ["CMD", "curl" ,"localhost:8090/health"]
      interval: 5s
      timeout: 1s
      retries: 10
    depends_on:
      apollo-configservice:
        condition: service_healthy

  apollo-portal:
    container_name: apollo-portal
    image: apolloconfig/apollo-portal:2.4.0
    restart: always
    ports:
      - 8070:8070
    environment:
    - SPRING_DATASOURCE_URL=jdbc:mysql://apollo-mysql:3306/ApolloPortalDB?characterEncoding=utf8&useSSL=false&serverTimezone=GMT
    - SPRING_DATASOURCE_USERNAME=root
    - SPRING_DATASOURCE_PASSWORD=WC85roj5IfwOhIEK
    # 注意这里,如果要修改不同环境名,则数据库也必须修改 ApolloPortalDB.ServerConfig 中 apollo.portal.envs 该行的信息,否则启动会发生报错
    - APOLLO_PORTAL_ENVS=dev
    # 这里需要写环境名对应的 configservice 服务地址。
    - DEV_META=http://apollo-configservice:8080
    volumes:
    - ./logs/portal:/opt/logs
    healthcheck:
      test: ["CMD", "curl" ,"localhost:8070/health"]
      interval: 5s
      timeout: 1s
      retries: 10
    depends_on:
      apollo-adminservice:
        condition: service_healthy
      apollo-configservice:
        condition: service_healthy

networks:
  default:
    name: apollo
    driver: bridge

注意事项:docker部署走的是docker网络内容环境,所以需要设置数据库中eureka.service.url配置为docker内容地址。

添加新的环境

ConfigService和AdminService服务连接的是ApolloConfigDB(配置库),所以需要新部署一套环境,需要有单独的ConfigService和AdminService服务以及数据库,这样才能保证不同环境的配置完全隔离。
如果想要同一数据库的情况下,可以划分不同的ApolloConfigDB库,比如:

  • dev 环境的 ConfigService + AdminService → 连接 ApolloConfigDB_DEV
  • pro 环境的 ConfigService + AdminService → 连接 ApolloConfigDB_PRO

假如我们新增加一个pro环境,操作如下:
1.新增加一套ConfigService和AdminService服务,还有数据库。
2.修改Portal服务配置文件config/apollo-env.properties,新增pro环境配置

dev.meta=http://dev环境apollo-configservice地址
pro.meta=http://pro环境apollo-configservice地址

或者可以添加环境变量的方式

DEV_META=http://dev环境apollo-configservice地址
PRO_META=http://pro环境apollo-configservice地址

3.修改Portal服务数据库apolloportaldb库下serverconfig表,Value字段新加一个新增的的环境,如下所示:

UPDATE `apolloportaldb`.`serverconfig` SET `Value` = 'dev,pro' WHERE `Key` = 'apollo.portal.envs';
UPDATE `apolloportaldb`.`serverconfig` SET `Value` = 'dev,pro' WHERE `Key` = 'configView.memberOnly.envs';

Apollo简单使用

首先我们需要创建应用,如下图所示:
apollo
创建好了之后我们可以选择环境来新建配置,如下图所示:
apollo
根据配置类型选择,配置类型为key-value的形式创建,可以选择环境进行创建,配置只会在选择的环境中创建,如下图所示:
apollo
创建好了之后我们可以看到配置的状态是未发布状态,我们需要进行发布才能使用,如下图所示:
apollo
发布中我们可以添加发布说明,可以看到发布的版本和信息,如下图所示:
apollo
发布完成之后可以看到新增配置的发布状态发生变化,成为了已发布状态,如下图所示:
apollo