Apollo远程配置中心
1 简介
Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
Apollo支持4个维度管理Key-Value格式的配置:
- application (应用)
- environment (环境)
- cluster (集群)
- namespace (命名空间)
同时,Apollo基于开源模式开发,开源地址:github.com/ctripcorp/a…
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的初始数据库连接数
以上内容来自官方文档:www.apolloconfig.com/#/zh/README
2 部署Apollo
2.1 Github下载
下载解压后的文件目录:
网络异常,图片无法展示
|
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比较多的一个来使用
下面我们按照步骤来使用下:
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(); } } 复制代码
网络异常,图片无法展示
|