docs/distributed-system/distributed-configuration-center.md
微服务架构下,业务发展通常会导致服务数量增加,进而导致程序配置(服务地址、数据库参数、功能开关等)增多。传统配置文件方式存在以下问题:
此外,配置中心通常提供以下增强能力:
| 方案 | 状态 | 特点 |
|---|---|---|
| Spring Cloud Config | 活跃 | Spring 生态原生支持,基于 Git 存储 |
| Nacos | 活跃 | 阿里开源,配置中心 + 服务发现二合一 |
| Apollo | 活跃 | 携程开源,配置管理功能最完善 |
| K8s ConfigMap | 活跃 | Kubernetes 原生方案 |
| Disconf / Qconf | 停止维护 | 不建议使用 |
选型建议:
Apollo vs Nacos vs Spring Cloud Config
版本说明:以下对比基于 Apollo 2.x、Nacos 2.x、Spring Cloud Config 3.x
| 功能点 | Apollo | Nacos | Spring Cloud Config |
|---|---|---|---|
| 配置界面 | 支持(功能完善) | 支持 | 无(通过 Git 操作) |
| 配置实时生效 | 支持(长轮询,1s 内) | 支持(gRPC 长连接,1s 内) | 半实时(需触发 refresh 或 Bus 广播) |
| 版本管理 | 原生支持 | 原生支持 | 依赖 Git |
| 权限管理 | 支持(细粒度) | 支持 | 依赖 Git 平台 |
| 灰度发布 | 支持(完善) | 支持(1.1.0+,基础) | 不支持 |
| 配置回滚 | 支持 | 支持 | 依赖 Git |
| 告警通知 | 支持 | 支持 | 不支持 |
| 多语言 | 支持(Open API) | 支持(Open API) | 仅 Spring 应用 |
| 多环境 | 支持 | 支持 | 需配合多 Git 仓库 |
| 依赖组件 | MySQL + Eureka | 内置存储(Derby/MySQL)+ JRaft | Git + 可选消息队列 |
深度对比:
设计或选型配置中心时,需关注以下能力:
| 模式 | 实时性 | 服务端压力 | 实现复杂度 | 适用场景 |
|---|---|---|---|---|
| 推模式 | 高(毫秒级) | 高(需维护连接) | 高 | 强实时性要求 |
| 拉模式 | 低(秒~分钟级) | 高(无效轮询) | 低 | 配置变更极少 |
| 长轮询 | 中高(1~30s) | 中等(海量连接时内存压力大) | 中 | 主流方案 |
推送机制说明:
- Apollo:采用 HTTP 长轮询。客户端发起请求,服务端若有变更立即返回;无变更则挂起请求(默认 30s),期间一旦有变更立即响应。
- Nacos 2.x:采用 gRPC 长连接双向流。相比 1.x 的 HTTP 长轮询,gRPC 连接更轻量,配置变更可毫秒级主动 Push 至客户端。
注意:长轮询虽然比短轮询节省 CPU 和网络开销,但当客户端规模达到十万级时,服务端需维持海量挂起的 HTTP 请求(依赖 Servlet AsyncContext),对内存和连接数上限仍有较大压力。
根据 Apollo 官方介绍:
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于 Spring Boot 和 Spring Cloud 开发,打包后可以直接运行,不需要额外安装 Tomcat 等应用容器。
Java 客户端不依赖任何框架,能够运行于所有 Java 运行时环境,同时对 Spring/Spring Boot 环境也有较好的支持。
Apollo 核心特性:
关于如何使用 Apollo 可以查看 Apollo 官方使用指南。
官方给出的 Apollo 基础模型:
官方架构图:
| 组件 | 作用 | 默认端口 |
|---|---|---|
| Portal | Web 管理界面,提供配置的可视化管理 | 8070 |
| Client | 客户端 SDK,提供配置获取和变更监听能力 | - |
| Meta Server | Eureka 的 HTTP 代理,与 Config Service 同进程 | 8080 |
| Config Service | 提供配置读取和推送接口,供 Client 调用 | 8080 |
| Admin Service | 提供配置管理接口,供 Portal 调用 | 8090 |
| Eureka | 服务注册中心,Config/Admin Service 注册于此 | 8761 |
| MySQL | 存储配置数据和元数据 | 3306 |
Client 端(获取配置):
/opt/data/ 或 /opt/logs/)灾备机制:即使 Config Service 全部宕机且应用重启,Client 仍可从本地磁盘读取缓存的配置完成启动,确保应用可用性不强依赖配置中心。
Portal 端(发布配置):
获取配置:
Config config = ConfigService.getAppConfig();
String someKey = "someKeyFromDefaultNamespace";
String someDefaultValue = "someDefaultValueForTheKey";
String value = config.getProperty(someKey, someDefaultValue);
监听配置变化:
Config config = ConfigService.getAppConfig();
config.addChangeListener(new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
// 处理配置变更
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format(
"Key: %s, Old: %s, New: %s",
key, change.getOldValue(), change.getNewValue()));
}
}
});