分布式配置中心面试题总结
为什么要用配置中心?
微服务架构下,业务发展通常会导致服务数量增加,进而导致程序配置(服务地址、数据库参数、功能开关等)增多。传统配置文件方式存在以下问题:
- 无法动态更新:配置放在代码库中,每次修改都需要重新发布新版本才能生效。
- 安全性不足:敏感配置(数据库密码、API Key)直接写在代码库中容易泄露。
- 时效性差:即使能修改配置文件,通常也需要重启服务才能生效。
- 缺乏权限控制:无法对配置的查看、修改、发布等操作进行细粒度权限管控。
- 配置分散难管理:多环境(开发/测试/生产)、多集群的配置分散在各处,难以统一维护。
此外,配置中心通常提供以下增强能力:
- 版本管理:记录每次配置变更的修改人、修改时间、修改内容,支持一键回滚。
- 灰度发布:先将配置推送给部分实例验证,降低变更风险(Apollo、Nacos 1.1.0+ 支持)。

常见的配置中心有哪些?如何选择?
| 方案 | 状态 | 特点 |
|---|---|---|
| Spring Cloud Config | 活跃 | Spring 生态原生支持,基于 Git 存储 |
| Nacos | 活跃 | 阿里开源,配置中心 + 服务发现二合一 |
| Apollo | 活跃 | 携程开源,配置管理功能最完善 |
| K8s ConfigMap | 活跃 | Kubernetes 原生方案 |
| Disconf / Qconf | 停止维护 | 不建议使用 |
选型建议:
- 只需配置中心 → Apollo(功能最完善)或 Nacos(上手更简单)
- 需要配置中心 + 服务发现 → Nacos
- Spring Cloud 体系且追求简单 → Spring Cloud Config
- Kubernetes 环境 → K8s ConfigMap 挂载 + 应用层文件监听(由于 Kubelet 同步 Volume 存在 1~2 分钟延迟,需引入 inotify 或 Spring Cloud Kubernetes 实现热重载)
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 + 可选消息队列 |
深度对比:
- Apollo:配置管理功能最完善(灰度发布、权限控制、审计日志),但部署复杂度较高。多环境(FAT/UAT/PROD)物理隔离场景下,需独立部署 Portal、Admin Service、Config Service 及独立数据库集群,运维门槛中等偏高
- Nacos:配置 + 注册中心二合一,部署简单(单机模式仅一个 Jar 包),但灰度等功能相对基础
- Spring Cloud Config:架构最简单(基于 Git),但实时性差,需要额外组件实现自动刷新
配置中心核心设计要点
设计或选型配置中心时,需关注以下能力:
1. 配置推送机制
| 模式 | 实时性 | 服务端压力 | 实现复杂度 | 适用场景 |
|---|---|---|---|---|
| 推模式 | 高(毫秒级) | 高(需维护连接) | 高 | 强实时性要求 |
| 拉模式 | 低(秒~分钟级) | 高(无效轮询) | 低 | 配置变更极少 |
| 长轮询 | 中高(1~30s) | 中等(海量连接时内存压力大) | 中 | 主流方案 |
推送机制说明:
- Apollo:采用 HTTP 长轮询。客户端发起请求,服务端若有变更立即返回;无变更则挂起请求(默认 30s),期间一旦有变更立即响应。
- Nacos 2.x:采用 gRPC 长连接双向流。相比 1.x 的 HTTP 长轮询,gRPC 连接更轻量,配置变更可毫秒级主动 Push 至客户端。
注意:长轮询虽然比短轮询节省 CPU 和网络开销,但当客户端规模达到十万级时,服务端需维持海量挂起的 HTTP 请求(依赖 Servlet AsyncContext),对内存和连接数上限仍有较大压力。
2. 必备功能清单
- 权限控制:配置的查看、修改、发布需分级授权
- 审计日志:完整记录配置变更的操作人、时间、内容
- 版本管理:每次发布生成版本号,支持回滚到任意历史版本
- 灰度发布:配置先推送到部分实例,验证通过后全量发布
- 多环境隔离:开发、测试、生产环境配置独立管理
- 高可用部署:配置中心自身需要集群化部署,避免单点故障
以 Apollo 为例介绍配置中心的设计
Apollo 介绍
根据 Apollo 官方介绍:
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于 Spring Boot 和 Spring Cloud 开发,打包后可以直接运行,不需要额外安装 Tomcat 等应用容器。
Java 客户端不依赖任何框架,能够运行于所有 Java 运行时环境,同时对 Spring/Spring Boot 环境也有较好的支持。
Apollo 核心特性:
- 配置修改实时生效(热发布):基于长轮询,1s 内即可接收到最新配置
- 灰度发布:配置只推给部分应用,降低变更风险
- 部署简单:单环境仅依赖 MySQL(Eureka 可使用内置模式),但多环境隔离部署复杂度较高
- 跨语言:提供了 HTTP 接口,不限制编程语言
关于如何使用 Apollo 可以查看 Apollo 官方使用指南。
Apollo 架构解析
官方给出的 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 端(获取配置):
- Client 启动时访问 Meta Server 获取 Config Service 地址列表
- Client 本地缓存服务地址(Eureka 故障时仍可用)
- Client 发起长轮询请求获取配置
- Config Service 检测到配置变更后立即响应
- Client 更新内存缓存、触发变更回调,并异步持久化到本地文件系统(默认位于
/opt/data/或/opt/logs/)
灾备机制:即使 Config Service 全部宕机且应用重启,Client 仍可从本地磁盘读取缓存的配置完成启动,确保应用可用性不强依赖配置中心。
Portal 端(发布配置):
- 用户在 Portal 修改配置并点击发布
- Portal 调用 Admin Service 发布接口
- Admin Service 将配置写入 MySQL 并生成发布版本
- Config Service 通过长轮询通知 Client 配置已变更
- Client 重新拉取最新配置
Client 使用示例
获取配置:
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()));
}
}
});参考
这本《Java 面试指北》(后端面试通用)的内容经过反复打磨,质量极高,旨在帮助每一位 Java/后端求职者从容应对面试挑战。
用数据说话: 截至目前,专栏累计阅读量已突破 477.1W,收获点赞 5,118 个,评论互动 1,657 条。值得一提的是,评论区不仅仅是留言板,更是答疑区——几乎每一条提问,我都会用心回复,确保无疑问遗留。

《Java 面试指北》(点击链接即可查看详细介绍)的部分内容展示如下,你可以将其看作是 JavaGuide 的补充完善,两者可以配合使用。

下面是《Java 面试指北》收到的部分球友的真实反馈:

如果需要面试辅导(比如简历优化、一对一模拟问答、高频考点突击资料等),欢迎了解我的知识星球。已经坚持维护六年,内容持续更新,虽然是白菜价(0.4 元/天),但质量很高、服务也很全面,主打一个良心!
下面是星球提供的部分服务(点击下方图片即可获取知识星球的详细介绍):
下面是今年收到了部分好评,每一条都是真实存在的。我看到很多培训班或者机构通过虚构一些不存在的好评来欺骗他人购买高价服务(行业内非常常见),真的很难理解。

我有自己的原则,不割韭菜,用心做内容,真心希望帮助到你! 如果你感兴趣的话,不妨花 3 分钟左右看看星球的详细介绍:JavaGuide 知识星球详细介绍 。
这里再送一张 30 元的星球专属优惠券,数量有限(价格即将上调。老用户续费半价 ,微信扫码即可续费)!

🚀 入圈必做(干货满满,一定要看!):
无任何套路,无任何潜在收费项。用心做内容,不割韭菜!
不过, 一定要确定需要再进 。并且, 三天之内觉得内容不满意可以全额退款 。


