官方文档:https://www.apolloconfig.com/#/zh/README
1 简介
Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
Apollo 支持 4 个维度管理 Key-Value 格式的配置:
application (应用)
environment (环境)
cluster (集群)
namespace (命名空间)
同时,Apollo 基于开源模式开发,开源地址:https://github.com/ctripcorp/apollo
1.1 Apollo 特性
正是基于配置的特殊性,所以 Apollo 从设计之初就立志于成为一个有治理能力的配置发布平台,目前提供了以下的特性:
统一管理不同环境、不同集群的配置
Apollo 提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
同一份代码部署在不同的集群,可以有不同的配置,比如 zookeeper 的地址等
通过命名空间(namespace)可以很方便地支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
配置修改实时生效(热发布)
用户在 Apollo 修改完配置并发布后,客户端能实时(1 秒)接收到最新的配置,并通知到应用程序
版本发布管理
所有的配置发布都有版本概念,从而可以方便地支持配置的回滚
灰度发布
支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例
权限管理、发布审核、操作审计
应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
所有的操作都有审计日志,可以方便地追踪问题
客户端配置信息监控
可以在界面上方便地看到配置在被哪些实例使用
提供 Java 和.Net 原生客户端
提供了 Java 和.Net 的原生客户端,方便应用集成
支持 Spring Placeholder, Annotation 和 Spring Boot 的 ConfigurationProperties,方便应用使用(需要 Spring 3.1.1+)
同时提供了 Http 接口,非 Java 和.Net 应用也可以方便地使用
提供开放平台 API
Apollo 自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过 Apollo 出于通用性考虑,不会对配置的修改做过多限制,只要符合基本的格式就能保存,不会针对不同的配置值进行针对性的校验,如数据库用户名、密码,Redis 服务地址等
对于这类应用配置,Apollo 支持应用方通过开放平台 API 在 Apollo 进行配置的修改和发布,并且具备完善的授权和权限控制
部署简单
配置中心作为基础服务,可用性要求非常高,这就要求 Apollo 对外部依赖尽可能地少
目前唯一的外部依赖是 MySQL,所以部署非常简单,只要安装好 Java 和 MySQL 就可以让 Apollo 跑起来
Apollo 还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
1.2 基础模型
1.3 核心概念
在介绍高级特性前,我们有必要先来了解一下 Apollo 中的几个核心概念:
application (应用)
这个很好理解,就是实际使用配置的应用,Apollo 客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置
每个应用都需要有唯一的身份标识 -- appId。
environment (环境)
配置对应的环境,Apollo 客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置
我们认为环境和代码无关,同一份代码部署在不同的环境就应该能够获取到不同环境的配置
所以环境默认是通过读取机器上的配置(server.properties 中的 env 属性)指定的,不过为了开发方便,我们也支持运行时通过 System Property 等指定,具体信息请参见Java客户端使用指南。
cluster (集群)
一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。
对不同的 cluster,同一个配置可以有不一样的值,如 zookeeper 地址。
集群默认是通过读取机器上的配置(server.properties 中的 idc 属性)指定的,不过也支持运行时通过 System Property 指定,具体信息请参见Java客户端使用指南。
namespace (命名空间)
一个应用下不同配置的分组,可以简单地把 namespace 类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC 配置文件,应用自身的配置文件等
应用可以直接读取到公共组件的配置 namespace,如 DAL,RPC 等
应用也可以通过继承公共组件的配置 namespace 来对公共组件的配置做调整,如 DAL 的初始数据库连接数
以上内容来自官方文档:https://www.apolloconfig.com/#/zh/README
2 部署 Apollo
2.1 Github 下载
下载地址:https://github.com/apolloconfig/apollo-build-scripts
下载解压后的文件目录:
2.2 构建数据库
根据官方文档的要求,MySQL 数据库版本必须在5.6.5
以上
有了 MySQL 数据库之后,我们需要新建两个数据库ApolloConfigDB
和ApolloPortalDB
然后导入 sql 目录中的两个 sql 文件
可以使用 Navicat 等图形化界面,也可以使用命令插入
source xxx.sql. -- sql文件的全绝对路径和文件名
复制代码
接下来看看我们导入成功没有:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| ApolloConfigDB |
| ApolloPortalDB |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
mysql> use ApolloConfigDB
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
+-------------+---------+-------+----------------------+
| NamespaceId | Key | Value | Comment |
+-------------+---------+-------+----------------------+
| 1 | timeout | 100 | sample timeout配置 |
+-------------+---------+-------+----------------------+
2 rows in set (0.00 sec)
mysql> use ApolloPortalDB
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
+----+-----------+------------+
| Id | AppId | Name |
+----+-----------+------------+
| 1 | SampleApp | Sample App |
+----+-----------+------------+
1 row in set (0.00 sec)
mysql>
复制代码
可以查询到数据的话就表示数据插入成功了
2.3 修改启动文件,启动项目并访问
修改启动文件demo.sh
,主要是 24-32 行的数据库配置
# apollo config db info
apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_config_db_username=root #改成自己的数据库的链接、用户名和密码
apollo_config_db_password=12345678
# apollo portal db info
apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_portal_db_username=root
apollo_portal_db_password=12345678
复制代码
启动项目
xxxx@xxxx apollo-build-scripts-master % ./demo.sh start
==== starting service ====
Service logging file is ./service/apollo-service.log
Already running [90548]
Waiting for config service startup
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [91099]
Waiting for portal startup..........
Portal started. You can visit http://localhost:8070 now!
复制代码
访问系统,Apollo 系统登陆的默认用户名是:apollp
密码是:admin
Eureka 的地址:localhost:8080
Apollp 的地址:localhost:8070
3 实践应用
3.1 本地启动并测试 Apollo
3.2 Go 使用 Apollo 作为远程配置中心
Go 连接 Apollo 的客户端有很多,这里选择了一个 GitHub 上 start 比较多的一个来使用
开源地址:https://github.com/apolloconfig/agollo
下面我们按照步骤来使用下:
3.2.1 新建 Go Modules
3.2.2 增加依赖
go get -u github.com/apolloconfig/agollo/v4@latest
复制代码
3.2.3 新建文件
package main
import (
"fmt"
"github.com/apolloconfig/agollo/v4"
"github.com/apolloconfig/agollo/v4/env/config"
)
func main() {
c := &config.AppConfig{
AppID: "SampleApp",
Cluster: "dev",
IP: "http://127.0.0.1:8080",
//NamespaceName: "TEST1.go_test_1201",
NamespaceName: "application",
IsBackupConfig: true,
Secret: "56ffb5eb1f6c4aba9ab008508a123650",
}
client, err := agollo.StartWithConfig(func() (*config.AppConfig, error) {
return c, nil
})
if err != nil {
fmt.Println("初始化Apollo失败")
} else {
fmt.Println("初始化Apollo配置成功")
}
//Use your apollo key to test
cache := client.GetConfigCache(c.NamespaceName)
value, _ := cache.Get("timeout")
fmt.Println(value)
}
复制代码
3.2.4 测试
Apollo 远程:
3.3 Spring Boot 使用 Apllo 作为远程配置中心
3.3.1 新建 Spring Boot 项目,引入依赖
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client-config-data</artifactId>
<version>1.9.0</version>
</dependency>
复制代码
3.3.2 配置文件
# appid
app.id=SampleApp
# 服务器url
apollo.meta=http://localhost:8080
# 密钥
apollo.access-key.secret=56ffb5eb1f6c4aba9ab008508a123650
# 集群名称,不填为默认
apollo.cluster=
# 开启缓存
apollo.property.names.cache.enable=true
# 灰度发布使用
apollo.label=YOUR-APOLLO-LABEL
# namespace命名空间,多个用逗号链接
spring.config.import=apollo://application, apollo://TEST1.go_test_1201
复制代码
3.3.3 新建配置类
@Configuration
@EnableApolloConfig
@Component
public class ApolloConfig {
@Value("${timeout}")
private Long timeout;
@Value("${name:yan}") //yan为默认值
private String name;
public void printTimeout(){
System.out.println("--------timeout is-------"+timeout);
}
public void printName(){
System.out.println(name);
}
}
复制代码
3.3.4 测试(配置仍为上边相同的配置)
@SpringBootTest
class SpApolloApplicationTests {
@Autowired
private ApolloConfig apolloConfig;
@Test
void contextLoads() {
apolloConfig.printTimeout();
apolloConfig.printName();
}
}
复制代码
欢迎关注公众号
评论