人人都会AI编程

16.6 分布式配置中心:Nacos Config / Spring Cloud Config

更新时间:2026-07-11

微服务架构下,每个服务都可能部署多个实例,且需要适应开发、测试、生产等不同环境。如果每个服务都维护一份本地 application.yml,那么修改一个数据库地址或开关项就可能需要重新打包、部署,配置分散,维护成本极高。分布式配置中心的核心价值在于:将配置从应用中剥离,集中管理,动态下发,让应用本身更轻量和云原生化

Spring Cloud 生态为此提供了两种主流方案:Spring Cloud ConfigNacos Config(Spring Cloud Alibaba 体系)。两者风格不同,但都能实现配置的外部化与动态刷新。

16.6.1 Spring Cloud Config:经典的 Git 管理方案

Spring Cloud Config 提供了服务端(Config Server)与客户端(Config Client)的配套组件。它的典型工作模式是:配置内容存储在 Git(或 SVN、本地文件系统)中,Config Server 对外提供 REST API 拉取配置,各个微服务作为客户端在启动时向 Config Server 请求自己所需的那一份。

1. 搭建 Config Server

引入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

启动类标注 @EnableConfigServer,并在 application.yml 中配置 Git 仓库地址:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/your-repo/config-repo  # 配置文件存放的 Git 仓库
          search-paths: configs                          # 子目录
          username: your-user                            # 私有仓库需要
          password: your-password
server:
  port: 8888

Git 仓库中按约定存放配置文件,例如 order-service-dev.ymlorder-service-prod.yml。Config Server 会将其映射为 HTTP 端点:/{application}/{profile}

2. 客户端接入

微服务需要引入 spring-cloud-starter-config 依赖,并将 bootstrap.yml(优先级高于 application.yml)配置为:

spring:
  application:
    name: order-service
  cloud:
    config:
      uri: http://config-server:8888
      profile: dev

启动时,客户端会根据 spring.application.namespring.cloud.config.profile(或 spring.profiles.active)向 Config Server 请求 order-service-dev.yml,并将配置合并到 Environment 中。

3. 配置刷新

默认情况下,配置是一次性加载的。要想在应用运行时动态刷新配置,必须做两件事:

  • 在需要刷新的 Bean 上标注 @RefreshScope(例如 Controller 中使用 @Value 的属性)。
  • 手动触发刷新:客户端暴露 /actuator/refresh 端点,当 Git 配置变更后,需要调用该端点(通常配合 Spring Cloud Bus 和消息中间件实现广播刷新)。
@RestController
@RefreshScope
public class ConfigTestController {
    @Value("${custom.message:default}")
    private String message;

    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}

如果没有 @RefreshScope,即便调用 /actuator/refresh@Value 注入的值也不会更新。

优缺点分析

  • 优点:天然契合 Git 工作流,配置历史可追溯,适合有代码审查诉求的团队。
  • 缺点:强依赖 Git 服务,有一定的运维成本;配置刷新需要额外引入消息总线,链路稍长;客户端无法实时感知变化,必须靠人工或钩子触发刷新。

16.6.2 Nacos Config:集服务发现与配置于一体

Nacos 是阿里巴巴开源的一款集服务发现、配置管理于一体的平台,它提供可视化的控制台,配置变更后可主动推送给客户端,实现近乎实时的动态刷新。Spring Cloud Alibaba 对其进行了深度封装,使用体验非常顺畅。

1. 部署 Nacos Server

开发环境可以直接下载压缩包解压并启动:

# 单机模式启动(内嵌 Derby 数据库)
sh startup.sh -m standalone

访问 http://localhost:8848/nacos,默认用户名密码均为 nacos

2. 客户端接入

在微服务中引入依赖(Spring Cloud Alibaba 版本需与 Spring Cloud 匹配):

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

配置文件 bootstrap.yml 中指定 Nacos 服务器地址和 Data ID 生成规则:

spring:
  application:
    name: order-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml

根据约定,Nacos Config 会查找 Data ID 为 order-service.yaml(默认规则:${spring.application.name}.${file-extension})的配置项,也可通过 spring.cloud.nacos.config.prefixspring.cloud.nacos.config.group 进一步定制。

在 Nacos 控制台添加配置:配置管理 → 配置列表 → 新建配置,Data ID 填写 order-service.yaml,配置内容写入完整的 YAML 格式即可。最终环境中的配置优先级为:Nacos 远程配置 > 本地 bootstrap.yml > application.yml。

3. 动态刷新

这是 Nacos Config 最突出的优势之一。当你在控制台修改配置并发布后,Nacos 会通过长轮询机制通知所有客户端,客户端接收变更后自动刷新环境。只要 Bean 标注了 @RefreshScope 或使用了 @ConfigurationProperties,值就能实时生效,不需要任何额外的手动刷新调用。

示例:

@RestController
@RefreshScope
public class ConfigController {

    @Value("${user.max-login-attempt:3}")
    private int maxLoginAttempt;

    @GetMapping("/max-login-attempt")
    public int getMaxLoginAttempt() {
        return maxLoginAttempt;
    }
}

配置修改后再次请求这个接口,返回值会立刻更新。对于复杂的配置类,推荐使用 @ConfigurationProperties 配合 @RefreshScope(或直接在类上标注 @RefreshScope,虽然 @ConfigurationProperties 绑定本身无需该注解,但为了刷新需添加)。实际上,在 Spring Cloud Alibaba 2021.0.1 版本后,@ConfigurationProperties 配合 Nacos 可实现自动刷新,但仍建议显式加上 @RefreshScope 以保证兼容性。

此外,Nacos 支持配置变更监听,可以通过 NacosConfigManager 编程式获取。

4. 共享配置与多环境

实际项目中,多个服务可能有公共配置(如数据库连接池参数、日志格式)。Nacos 提供了 shared-configsextension-configs 来加载共享配置:

spring:
  cloud:
    nacos:
      config:
        shared-configs:
          - data-id: common-db.yaml
            group: DEFAULT_GROUP
            refresh: true

多环境可以通过 spring.profiles.active 影响 Data ID,如激活 dev 环境时,还会加载 order-service-dev.yaml

16.6.3 方案对比与选型建议

| 维度 | Spring Cloud Config | Nacos Config |
| -------------- | ---------------------------------- | -------------------------------------------- |
| 存储后端 | Git、SVN、本地文件 | Nacos 自带存储(默认 Derby/MySQL) |
| 可视化控制台 | 无(需第三方) | 内置控制台,支持在线编辑、发布、回滚 |
| 动态刷新机制 | 需手动调用 /actuator/refresh + Bus | 配置发布后自动推送,客户端实时生效 |
| 配置格式 | 支持 YAML/Properties 等,需按文件名约定 | 同样支持,且支持在控制台直接编辑 HTML、JSON 等 |
| 灰度发布 | 较为繁琐,依赖 Git 分支 | 支持按 IP、标签等维度进行灰度发布 |
| 运维复杂度 | 需要维护 Git 仓库及 Config Server 实例 | 依赖 Nacos 集群,但 Nacos 同时负责服务发现,平台统一 |
| 社区生态 | Spring 官方项目,国外使用广 | 阿里巴巴背书,国内文档丰富,活跃度高 |

选型建议

  • 如果你已经或计划使用 Nacos 作为服务发现和注册中心,直接采用 Nacos Config 是最自然的选择,集成、运维成本最低,动态刷新体验也更好。
  • 如果团队对 Git 管理配置有硬性合规要求(如所有配置必须代码审查、历史可审计),或者不希望引入额外的第三方平台,Spring Cloud Config 更为合适。
  • 对于配置项少、环境简单的项目,甚至可以只用本地配置文件 + Kubernetes ConfigMap,不必引入专门的配置中心;但一旦服务数量超过 5~10 个,集中配置管理就能显著降低心智负担。

在实际生产中,Nacos Config 的易用性让它成为国内许多中小团队的首选;而 Spring Cloud Config 更偏向与 GitOps 工作流深度融合。两者均为成熟方案,按需选取即可。