官方文档: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 ApolloConfigDBReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changedmysql> 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 ApolloPortalDBReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A
Database changedmysql> 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 infoapollo_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 infoapollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"apollo_portal_db_username=rootapollo_portal_db_password=12345678
复制代码
启动项目
xxxx@xxxx apollo-build-scripts-master % ./demo.sh start==== starting service ====Service logging file is ./service/apollo-service.logAlready running [90548]Waiting for config service startupConfig service started. You may visit http://localhost:8080 for service status now!Waiting for admin service startupAdmin service started==== starting portal ====Portal logging file is ./portal/apollo-portal.logStarted [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 配置文件
# appidapp.id=SampleApp# 服务器urlapollo.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@Componentpublic 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 测试(配置仍为上边相同的配置)
@SpringBootTestclass SpApolloApplicationTests {
@Autowired private ApolloConfig apolloConfig;
@Test void contextLoads() { apolloConfig.printTimeout(); apolloConfig.printName(); }
}
复制代码
欢迎关注公众号
评论