配置管理
配置管理是微服务架构中的核心基础设施之一。在分布式系统中,统一管理各服务的配置信息至关重要,配置中心应运而生。
为什么需要配置中心?
在传统的单体应用中,配置文件通常放在应用程序内部,修改配置需要重新部署。但在微服务架构中:
- 服务数量多:几十甚至上百个服务,配置分散难以管理
- 环境多样:开发、测试、预发布、生产等多套环境
- 动态更新:某些配置需要实时生效,无需重启服务
- 版本管理:配置变更需要追溯和回滚
传统配置管理:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 服务 A │ │ 服务 B │ │ 服务 C │
│ application.yml│ │ application.yml│ │ application.yml│
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
修改配置需要重新部署每个服务
配置中心架构:
┌─────────────────────────────────────────────────────┐
│ 配置中心 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 开发环境 │ │ 测试环境 │ │ 生产环境 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 服务 A │ │ 服务 B │ │ 服务 C │
└─────────────┘ └─────────────┘ └─────────────┘
统一管理,动态更新,版本追溯
主流配置中心对比
| 特性 | Spring Cloud Config | Nacos | Apollo |
|---|---|---|---|
| 开发者 | Spring 官方 | 阿里巴巴 | 携程 |
| 配置存储 | Git、文件系统、数据库 | 数据库 | 数据库 |
| 动态刷新 | 需要配合 Bus | 原生支持 | 原生支持 |
| 灰度发布 | 不支持 | 支持 | 支持 |
| 配置回滚 | Git 版本控制 | 支持 | 支持 |
| 控制台 | 无 | 完善 | 完善 |
| 学习成本 | 低 | 低 | 中 |
Spring Cloud Config
Spring Cloud Config 是 Spring 官方提供的配置中心解决方案,基于 Git 仓库存储配置文件。
架构组成
Spring Cloud Config 分为两个部分:
- Config Server:配置服务端,从 Git 仓库读取配置
- Config Client:配置客户端,从 Config Server 获取配置
┌─────────────────────────────────────────────────────────────┐
│ Spring Cloud Config 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Git 仓库 │ ◄────── │ Config │ │
│ │ 配置文件 │ │ Server │ │
│ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 服务 A │ │ 服务 B │ │ 服务 C │ │
│ │ Config │ │ Config │ │ Config │ │
│ │ Client │ │ Client │ │ Client │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
搭建 Config Server
添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
配置文件:
server:
port: 8888
spring:
cloud:
config:
server:
git:
# Git 仓库地址
uri: https://github.com/your-org/config-repo
# 搜索目录
search-paths: '{application}'
# 分支
default-label: main
# 认证信息(私有仓库需要)
username: your-username
password: your-password
启动类:
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
配置文件命名规则
Config Server 支持以下命名规则:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
示例:
config-repo/
├── user-service-dev.yml
├── user-service-test.yml
├── user-service-prod.yml
└── order-service-dev.yml
访问 http://localhost:8888/user-service/dev 即可获取配置。
Config Client 配置
添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
bootstrap.yml 配置:
spring:
application:
name: user-service
profiles:
active: dev
cloud:
config:
uri: http://localhost:8888
# 快速失败
fail-fast: true
# 重试配置
retry:
initial-interval: 1000
max-attempts: 6
max-interval: 2000
multiplier: 1.1
注意:Spring Boot 2.4+ 之后,需要添加 spring-cloud-starter-bootstrap 依赖才能使用 bootstrap.yml,或者使用 spring.config.import 配置:
spring:
application:
name: user-service
config:
import: optional:configserver:http://localhost:8888
配置动态刷新
Spring Cloud Config 默认不支持自动刷新,需要配合 Spring Cloud Bus 或手动刷新。
手动刷新:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
endpoints:
web:
exposure:
include: refresh
在需要刷新的类上添加 @RefreshScope 注解:
@RestController
@RefreshScope
public class ConfigController {
@Value("${app.message:default}")
private String message;
@GetMapping("/message")
public String getMessage() {
return message;
}
}
刷新配置:
curl -X POST http://localhost:8080/actuator/refresh
Nacos Config
Nacos 是阿里巴巴开源的配置中心和服务发现组件,提供了更强大的配置管理能力。
Nacos Config 特点
- 动态配置:配置变更实时推送,无需重启
- 命名空间隔离:支持多环境、多租户隔离
- 配置分组:按业务分组管理配置
- 灰度发布:支持配置的灰度发布
- 历史版本:配置变更历史可追溯
添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
配置文件
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
# 命名空间(环境隔离)
namespace: dev
# 分组
group: DEFAULT_GROUP
# 文件扩展名
file-extension: yml
# 共享配置
shared-configs:
- data-id: common.yml
group: DEFAULT_GROUP
refresh: true
# 扩展配置
extension-configs:
- data-id: redis.yml
group: DEFAULT_GROUP
refresh: true
Data ID 命名规则
Nacos 中配置的 Data ID 通常遵循以下格式:
${prefix}-${spring.profiles.active}.${file-extension}
prefix:默认为spring.application.namespring.profiles.active:当前环境file-extension:配置文件扩展名
示例:
user-service-dev.yml # 开发环境配置
user-service-test.yml # 测试环境配置
user-service-prod.yml # 生产环境配置
动态刷新
Nacos Config 原生支持配置动态刷新:
@RestController
@RefreshScope
public class ConfigController {
@Value("${app.config.value:default}")
private String configValue;
@GetMapping("/config")
public String getConfig() {
return configValue;
}
}
当在 Nacos 控制台修改配置后,应用会自动接收更新。
配置监听
可以监听特定配置的变化:
@Component
public class ConfigListener {
@NacosConfigListener(dataId = "user-service.yml", groupId = "DEFAULT_GROUP")
public void onConfigChange(String newConfig) {
log.info("配置发生变化: {}", newConfig);
}
}
多配置文件加载
Nacos 支持加载多个配置文件:
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yml
# 共享配置(所有服务共享)
shared-configs:
- data-id: common.yml
refresh: true
# 扩展配置(特定服务需要)
extension-configs:
- data-id: datasource.yml
refresh: true
- data-id: redis.yml
refresh: true
加载优先级(从高到低):
- 主配置
${spring.application.name}-${profile}.${file-extension} - 扩展配置
extension-configs(按数组顺序) - 共享配置
shared-configs
命名空间与分组
Nacos 通过命名空间和分组实现多环境隔离:
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
# 命名空间 ID(在 Nacos 控制台创建)
namespace: a1b2c3d4-e5f6-7890-abcd-ef1234567890
# 分组名称
group: USER_GROUP
命名空间:用于隔离不同环境(开发、测试、生产)
分组:用于隔离不同项目或业务模块
┌─────────────────────────────────────────────────────────────┐
│ Nacos 配置隔离模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 命名空间: dev │
│ ├── 分组: USER_GROUP │
│ │ ├── user-service.yml │
│ │ └── auth-service.yml │
│ └── 分组: ORDER_GROUP │
│ └── order-service.yml │
│ │
│ 命名空间: prod │
│ ├── 分组: USER_GROUP │
│ │ └── user-service.yml │
│ └── 分组: ORDER_GROUP │
│ └── order-service.yml │
│ │
└─────────────────────────────────────────────────────────────┘
配置加密
敏感配置(如数据库密码)需要加密存储。
对称加密
Config Server 配置:
encrypt:
key: your-secret-key
加密配置:
# 加密
curl http://localhost:8888/encrypt -d my-secret-password
# 解密
curl http://localhost:8888/decrypt -d <encrypted-value>
配置文件中使用:
spring:
datasource:
password: '{cipher}<encrypted-value>'
非对称加密
生成密钥对:
keytool -genkeypair -alias config-server-key \
-keyalg RSA -keysize 2048 \
-keystore config-server.jks \
-storepass changeit
Config Server 配置:
encrypt:
key-store:
location: classpath:/config-server.jks
password: changeit
alias: config-server-key
secret: changeit
最佳实践
1. 配置分类管理
配置中心
├── 公共配置
│ ├── common.yml # 全局公共配置
│ ├── datasource.yml # 数据源配置
│ └── redis.yml # Redis 配置
├── 服务配置
│ ├── user-service.yml # 用户服务配置
│ ├── order-service.yml # 订单服务配置
│ └── product-service.yml # 商品服务配置
└── 环境配置
├── user-service-dev.yml
├── user-service-test.yml
└── user-service-prod.yml
2. 敏感配置加密
所有敏感配置必须加密存储:
spring:
datasource:
username: app_user
password: '{cipher}AQCGy1r...'
3. 配置变更审计
启用配置变更审计,记录每次变更:
- 变更时间
- 变更人
- 变更内容
- 变更原因
4. 配置回滚
配置变更前做好备份,支持快速回滚:
# Nacos 控制台支持一键回滚到历史版本
5. 灰度发布
重要配置变更使用灰度发布:
- 先在测试环境验证
- 选择部分实例应用新配置
- 观察无异常后全量发布
小结
本章我们学习了:
- 配置中心的作用:统一管理微服务配置
- Spring Cloud Config:基于 Git 的配置中心
- Nacos Config:功能更强大的配置中心
- 配置动态刷新:实时更新配置
- 配置加密:保护敏感配置