写点什么

初探 Apollo 远程服务配置中心

作者:Barry Yan
  • 2022-11-11
    北京
  • 本文字数:4431 字

    阅读完需:约 15 分钟

官方文档:https://www.apolloconfig.com/#/zh/README

1 简介

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


Apollo 支持 4 个维度管理 Key-Value 格式的配置:


  1. application (应用)

  2. environment (环境)

  3. cluster (集群)

  4. 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 中的几个核心概念:


  1. application (应用)

  2. 这个很好理解,就是实际使用配置的应用,Apollo 客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置

  3. 每个应用都需要有唯一的身份标识 -- appId。

  4. environment (环境)

  5. 配置对应的环境,Apollo 客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置

  6. 我们认为环境和代码无关,同一份代码部署在不同的环境就应该能够获取到不同环境的配置

  7. 所以环境默认是通过读取机器上的配置(server.properties 中的 env 属性)指定的,不过为了开发方便,我们也支持运行时通过 System Property 等指定,具体信息请参见Java客户端使用指南

  8. cluster (集群)

  9. 一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。

  10. 对不同的 cluster,同一个配置可以有不一样的值,如 zookeeper 地址。

  11. 集群默认是通过读取机器上的配置(server.properties 中的 idc 属性)指定的,不过也支持运行时通过 System Property 指定,具体信息请参见Java客户端使用指南

  12. namespace (命名空间)

  13. 一个应用下不同配置的分组,可以简单地把 namespace 类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC 配置文件,应用自身的配置文件等

  14. 应用可以直接读取到公共组件的配置 namespace,如 DAL,RPC 等

  15. 应用也可以通过继承公共组件的配置 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 数据库之后,我们需要新建两个数据库ApolloConfigDBApolloPortalDB


然后导入 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(); }
}
复制代码



欢迎关注公众号



发布于: 刚刚阅读数: 5
用户头像

Barry Yan

关注

做兴趣使然的Hero 2021-01-14 加入

Just do it.

评论

发布
暂无评论
初探Apollo远程服务配置中心_阿波罗_Barry Yan_InfoQ写作社区