目录
. 一、基本概念
. 1、背景
. 2、简介
. 3、特点
. 4、基础模型
. 5、架构模块
. 6、Apollo 核心概念
. 7、Apollo 和Spring cloud Config对比
. 二、Apollo 配置中心创建项目与配置
. 1、登录 Apollo
. 2、修改与增加部门数据
. 3、创建一个项目
. 4、创建一个配置参数
. 三、创建 Apollo 客户端测试项目
. 1、Mavne 添加 Apollo 依赖
. 2、配置文件添加参数
. 3、创建测试 Controller 类
. 4、创建启动类
. 5、配置一个常量参数类
. 6、客户端监听配置变化
. 7、跳过Apollo Meta Server服务发现
目录
系统环境
- SpringBoot 版本:2.2.6.RELEASE
- apollo-client 版本:1.5.0
参考地址
一、基本概念
由于 Apollo 概念比较多,刚开始使用比较复杂,最好先过一遍概念再动手实践尝试使用。
1、背景
随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……
对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……
在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。Apollo 配置中心应运而生!
2、简介
Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。
3、特点
- 统一管理不通环境、不同集群的配置
- 配置修改实时生效
- 版本发布管理
- 灰度发布
- 权限管理、发布审核、操作审计
- 部署简单
4、基础模型
如下即是 Apollo 的基础模型:
- 用户在配置中心对配置进行修改并发布
- 配置中心通知Apollo客户端有配置更新
- Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用

5、架构模块
下图是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、错误重试
- 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中
6、Apollo 核心概念
1、application(应用)
- 这个很好理解,就是实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置
- 每个应用都需要有唯一的身份标识 -- appId,我们认为应用身份是跟着代码走的,所以需要在代码中配置,具体信息请参见Java客户端使用指南。
2、environment(环境)
- 配置对应的环境,Apollo客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置
- 我们认为环境和代码无关,同一份代码部署在不同的环境就应该能够获取到不同环境的配置
- 所以环境默认是通过读取机器上的配置(server.properties中的env属性)指定的,不过为了开发方便,我们也支持运行时通过System Property等指定,具体信息请参见Java客户端使用指南。
3、cluster(集群)
- 一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。
- 对不同的cluster,同一个配置可以有不一样的值,如zookeeper地址
- 集群默认是通过读取机器上的配置(server.properties中的idc属性)指定的,不过也支持运行时通过System Property指定,具体信息请参见Java客户端使用指南。
4、namespace(命名空间)
- 一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等
- 应用可以直接读取到公共组件的配置namespace,如DAL,RPC等
- 应用也可以通过继承公共组件的配置namespace来对公共组件的配置做调整,如DAL的初始数据库连接数
7、Apollo 和Spring cloud Config对比

结论: Apollo相对于Spring Cloud Config的生态支持更广,在配置管理流程上做的更好。
二、普通应用接入指南
1.1 创建项目
要使用Apollo,第一步需要创建项目。
- 打开apollo-portal主页
- 点击“创建项目”

- 输入项目信息
- 部门:选择应用所在的部门
- 应用AppId:用来标识应用身份的唯一id,格式为string,需要和客户端app.properties中配置的app.id对应
- 应用名称:应用名,仅用于界面展示
- 应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限

Apollo没有提供新增部门的选项,修改或者添加部门只能通过修改数据库实现,这里打开 ApolloPortalDB 对应的数据库中的表 ServerConfig 修改 key 为 organizations 的 value 的 json 数据,改成自己对于的部门信息。

-
点击提交
创建成功后,会自动跳转到项目首页

1.2 项目权限分配
1.2.1 项目管理员权限
项目管理员拥有以下权限:
- 可以管理项目的权限分配
- 可以创建集群
- 可以创建Namespace
创建项目时填写的应用负责人默认会成为项目的管理员之一,如果还需要其他人也成为项目管理员,可以按照下面步骤操作:
- 点击页面左侧的“管理项目”
- 搜索需要添加的成员并点击添加
1.2.1 配置编辑、发布权限
配置权限分为编辑和发布:
- 编辑权限允许用户在Apollo界面上创建、修改、删除配置
- 配置修改后只在Apollo界面上变化,不会影响到应用实际使用的配置
- 发布权限允许用户在Apollo界面上发布、回滚配置
- 配置只有在发布、回滚动作后才会被应用实际使用到
- Apollo在用户操作发布、回滚动作后实时通知到应用,并使最新配置生效
项目创建完,默认没有分配配置的编辑和发布权限,需要项目管理员进行授权。
- 点击application这个namespace的授权按钮
- 分配修改权限
1.3 添加配置项
编辑配置需要拥有这个Namespace的编辑权限,如果发现没有新增配置按钮,可以找项目管理员授权。
1.3.1 通过表格模式添加配置
- 点击新增配置
- 输入配置项
- 点击提交
1.3.2 通过文本模式编辑
Apollo除了支持表格模式,逐个添加、修改配置外,还提供文本模式批量添加、修改。 这个对于从已有的properties文件迁移尤其有用。
- 切换到文本编辑模式

- 点击右侧的修改配置按钮

- 输入配置项,并点击提交修改

1.4 发布配置
配置只有在发布后才会真的被应用使用到,所以在编辑完配置后,需要发布配置。
发布配置需要拥有这个Namespace的发布权限,如果发现没有发布按钮,可以找项目管理员授权。
- 点击“发布按钮”

- 填写发布相关信息,点击发布

更多配置信息参考Apollo使用指南
三、创建 Apollo 客户端测试项目
这里创建一个 SpringBoot 项目,引入 Apollo 客户端来来实现与 Apollo 配置中心服务端交互。
1、Maven 添加 Apollo 依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>rock-apollo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rock-apollo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.6.RELEASE</version>
</plugin>
</plugins>
</build>
</project>
2、配置文件添加参数
在/resources下添加META-INF文件夹以及在META-INF下新增app.properties文件,参数如下:
- app.id : Apollo配置的AppId唯一标识
- applo.meta: Apollo 配置中心地址
app.id=85648775
apollo.meta=http://localhost:8080
在 application.yml 配置文件中添加下面参数,这里简单介绍下 Apollo 参数作用:
- apollo.cluster: 指定使用某个集群下的配置。
- apollo.bootstrap.enabled: 是否开启 Apollo。
- apollo.bootstrap.namespaces : 指定使用哪个 Namespace 的配置,默认 application。
- apollo.bootstrap.eagerLoad.enabled : 将 Apollo 加载提到初始化日志系统之前,如果设置为 false,那么将打印出 Apollo 的日志信息,但是由于打印 Apollo 日志信息需要日志先启动,启动后无法对日志配置进行修改,所以 Apollo 不能管理应用的日志配置,如果设置为 true,那么 Apollo 可以管理日志的配置,但是不能打印出 Apollo 的日志信息。
server:
port: 8888
spring:
application:
name: rock-apollo
#Apollo配置
apollo:
cluster: default #指定使用哪个集群的配置
bootstrap:
enabled: true #是否开启Apollo
namespace: application.notice #设置namespace
eagerLoad:
enabled: false #将Apollo 加载提到初始化日志系统之前
3、创建测试 Controller 类
package com.example.rockapollo.controller;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.example.rockapollo.config.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ApolloController {
@Value("${name:test}")
private String name;
@Autowired
private Constant constant;
@GetMapping("/getName")
public String getName(){
return name;
}
@GetMapping("/config")
public String config(){
return ConfigService.getAppConfig().getProperty("name",null);
}
@GetMapping("/getNoticeName")
public String getNoticeName(){
Config notice = ConfigService.getConfig("notice");
return notice.getProperty("address",null);
}
@GetMapping("/constant")
public Constant getConstant(){
return constant;
}
}
4、创建启动类
package com.example.rockapollo;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableApolloConfig
public class RockApolloApplication {
public static void main(String[] args) {
SpringApplication.run(RockApolloApplication.class, args);
}
}
5、配置一个常量参数类
package com.example.rockapollo.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class Constant {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
@Value("${address}")
private String address;
}
6、客户端监听配置变化
在某些场景下,应用还需要在配置变化时获得通知,比如数据库连接的切换等,所以Apollo还提供了监听配置变化的功能,Java示例如下:
package com.example.rockapollo.listener;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class ApolloChangeListenerImpl implements ConfigChangeListener {
/**
* .监听Apollo 配置变化
* @ApolloConfigChangeListener 监听指定namespace的配置
* @param configChangeEvent
*/
@Override
@ApolloConfigChangeListener("notice")
public void onChange(ConfigChangeEvent configChangeEvent) {
for (String changedKey : configChangeEvent.changedKeys()) {
ConfigChange change = configChangeEvent.getChange(changedKey);
log.warn("found change - key:{},oldValue:{},newValue:{},changeType:{}",
change.getPropertyName(), change.getOldValue(), change.getNewValue(),change.getChangeType());
}
}
}
7、跳过Apollo Meta Server服务发现
一般情况下都建议使用Apollo的Meta Server机制来实现Config Service的服务发现,从而可以实现Config Service的高可用。不过apollo-client也支持跳过Meta Server服务发现,主要用于以下场景:
Config Service部署在公有云上,注册到Meta Server的是内网地址,本地开发环境无法直接连接
Config Service部署在docker环境中,注册到Meta Server的是docker内网地址,本地开发环境无法直接连接
Config Service部署在kubernetes中,希望使用kubernetes自带的服务发现能力(Service)
针对以上场景,可以通过直接指定Config Service地址的方式来跳过Meta Server服务发现,按照优先级从高到低分别为:
-
通过Java System Property
apollo.configService-
可以通过Java的System Property
apollo.configService来指定 -
在Java程序启动脚本中,可以指定
-Dapollo.configService=http://config-service-url:port- 如果是运行jar文件,需要注意格式是
java -Dapollo.configService=http://config-service-url:port -jar xxx.jar
- 如果是运行jar文件,需要注意格式是
-
也可以通过程序指定,如
System.setProperty("apollo.configService", "http://config-service-url:port");
Intellij IDEA 内可以通过VM配置启动
-
-
通过操作系统的System Environment
APOLLO_CONFIGSERVICE- 可以通过操作系统的System Environment
APOLLO_CONFIGSERVICE来指定 - 注意key为全大写,且中间是
_分隔
- 可以通过操作系统的System Environment
-
通过
server.properties配置文件
- 可以在
server.properties配置文件中指定apollo.configService=http://config-service-url:port - 对于Mac/Linux,文件位置为
/opt/settings/server.properties - 对于Windows,文件位置为
C:\opt\settings\server.properties
- 可以在







