微服务架构下,每个服务都可能部署多个实例,且需要适应开发、测试、生产等不同环境。如果每个服务都维护一份本地 application.yml,那么修改一个数据库地址或开关项就可能需要重新打包、部署,配置分散,维护成本极高。分布式配置中心的核心价值在于:将配置从应用中剥离,集中管理,动态下发,让应用本身更轻量和云原生化。
Spring Cloud 生态为此提供了两种主流方案:Spring Cloud Config 和 Nacos 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.yml、order-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.name 和 spring.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.prefix 和 spring.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-configs 和 extension-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 工作流深度融合。两者均为成熟方案,按需选取即可。