Skip to content

配置中心设计:Nacos vs Apollo vs Spring Cloud Config,配置实时刷新原理

为什么需要配置中心?

微服务架构下,一个系统通常有几十上百个服务实例,每个服务都有自己的一套配置——数据库连接、日志级别、限流阈值、功能开关……如果这些配置散落在每个服务的本地配置文件里,每次修改都需要:

  • 改配置 → 提交代码 → CI/CD 构建 → 重新部署 → 重启服务
  • 十几台机器一台一台改,漏改了一台,线上出问题才排查到

配置中心就是为了解决这个问题:让配置与代码分离,支持动态修改、实时生效,不需要重启服务

三大主流配置中心对比

1. Spring Cloud Config

Spring 官方出品,最轻量的方案。核心思路是把配置存在 Git 仓库里,服务通过配置中心 Server 拉取配置。

架构:Git 仓库 → Config Server(读取 Git 配置)→ 微服务客户端(从 Config Server 拉取)

配置刷新:默认不自动刷新。配置变更后,需要调用 POST /actuator/refresh 端点手动触发,或者配合 Spring Cloud Bus 广播刷新消息到所有服务实例。

优点

  • 开箱即用,Spring Boot 项目集成成本极低
  • 基于 Git 存储,天然支持版本管理和回滚
  • 不需要额外部署存储组件

缺点

  • 不提供配置管理界面,改配置要用 Git 命令
  • 不支持实时推送,需要手动触发或依赖 Bus 广播
  • 没有灰度发布能力
  • 权限管理弱,谁都能改 Git 仓库

2. Apollo

携程开源的配置中心,国内使用最广泛,功能最完善。

架构:Portal(管理界面)→ ConfigService(配置服务)→ MetaServer(元数据服务)→ AdminService(管理服务)→ 客户端

配置刷新:客户端通过长轮询(Long Polling)感知配置变更——客户端发起一个 30 秒超时的 HTTP 请求到 ConfigService,如果配置没变,服务器等待 30 秒后返回 304;如果配置变了,立即返回变更内容。客户端收到变更后,更新本地缓存,触发 Spring 的 @RefreshScope Bean 重建。

优点

  • 功能最全:配置管理界面、灰度发布、权限管理、多环境/多集群隔离
  • 配置变更感知快,默认 1 秒内生效
  • 支持配置的版本管理和回滚,每次变更都有记录
  • 支持配置的监听和通知,可以自定义回调逻辑

缺点

  • 组件多,部署复杂(Portal + ConfigService + AdminService + MetaServer + Eureka + 数据库)
  • 资源占用较高,小规模团队可能觉得重

3. Nacos

阿里开源,注册中心和配置中心二合一,v2 版本全面升级为 gRPC 通信。

架构:Nacos Server(集群,至少 3 节点)→ 客户端(gRPC 长连接)

配置刷新:Nacos v2 通过 gRPC 长连接实现配置变更推送。客户端与服务端建立 gRPC 长连接,配置变更时服务端主动推送。相比 Apollo 的长轮询,gRPC 长连接省去了频繁的 HTTP 请求开销,网络资源占用更少。

优点

  • 配置中心和注册中心一体化,减少运维组件
  • v2 版本 gRPC 推送实时性高,毫秒级感知
  • 支持配置版本管理和回滚
  • 轻量级部署,支持内嵌 Derby 数据库(开发环境)或 MySQL 集群(生产环境)

缺点

  • 配置管理界面功能不如 Apollo 丰富(如无灰度发布)
  • 配置变更的审批流程不如 Apollo 完善

配置实时刷新原理

三种方案虽然实现方式不同,但核心逻辑是一样的:

  1. 运维人员在控制台/代码仓库修改配置
  2. 配置中心通知客户端配置变更(Nacos 用 gRPC 长连接推送,Apollo 用长轮询,Spring Cloud Config 用 Bus 广播)
  3. 客户端拉取最新配置
  4. Spring 刷新 Environment 上下文 + 重建 @RefreshScope Bean

关键在于 @RefreshScope:Spring 会把标记了 @RefreshScope 的 Bean 缓存起来,配置刷新时销毁旧 Bean 实例,然后重新创建新的 Bean 实例,新实例从更新后的 Environment 中读取配置。

java
@Component
@RefreshScope
public class DynamicConfig {
    @Value("${order.timeout:30}")
    private int orderTimeout;
    
    public int getOrderTimeout() {
        return orderTimeout;
    }
}

当配置中心的 order.timeout 从 30 改成 60 时,DynamicConfig 这个 Bean 会被重建,orderTimeout 字段自动更新为 60。

选型建议

维度Spring Cloud ConfigApolloNacos
部署复杂度
配置管理界面完善基础
灰度发布不支持支持不支持
实时推送需 Bus 配合长轮询,1s 内gRPC 推送,毫秒级
权限管理完善基础
存储Git数据库数据库/内嵌 Derby
最佳规模50 个服务以内50-200 个服务200 个以上服务

经验法则

  • 团队 10 人以下、服务 20 个以内:Spring Cloud Config + Git 完全够用,别折腾
  • 服务 50-200 个,需要配置管理界面和灰度发布:Apollo 最合适
  • 服务 200 个以上,已经用了 Nacos 做注册中心直接复用:Nacos 二合一,减少运维组件

配置变更的安全红线

配置中心能动态改配置,意味着改错配置的杀伤力比改错代码还大——代码改错要部署上线才能生效,配置改错秒级全量推送。

生产事故案例:某公司运维在 Nacos 控制台误将生产环境的数据库连接池大小从 50 改为 5,配置直接推送到所有 20 个实例,数据库连接池瞬间打满,服务大面积瘫痪。

三件事必做

  1. 关键配置变更走审批流程——数据库连接、线程池大小、熔断阈值等参数,修改前必须审批
  2. 灰度发布——先在 1% 的实例上应用新配置,观察 5 分钟无异常再全量推送(Apollo 原生支持,Nacos 需配合其他工具)
  3. 配置变更审计——每次变更记录操作人、变更内容、时间,便于事后回溯

总结

  • 配置中心不是锦上添花,是微服务的标配基础设施——没有配置中心,几十个服务的配置管理就是灾难
  • 选型看规模和团队能力:小团队用 Spring Cloud Config 够用,中大型团队选 Apollo 或 Nacos
  • 配置变更比代码变更更危险——必须建立审批和灰度机制
  • 配置与代码分离是核心思想,但别忘了配置本身也需要版本管理——回滚能力和 Git 一样重要

手撕 → 框架 → 生产化,一步步把 AI Agent 工程化搞透。