Appearance
分布式配置中心
分布式配置中心是微服务架构中的核心组件,用于集中管理各个环境中的应用配置,实现配置的动态更新。Spring Cloud Config 提供了配置服务器和客户端支持,简化了分布式系统中的配置管理。
为什么需要分布式配置中心?
在微服务架构中,配置管理面临以下挑战:
- 服务数量多:随着服务数量增加,配置文件管理变得困难
- 配置环境多:开发、测试、生产等多环境配置需要管理
- 配置变更频繁:频繁的配置变更需要有效的版本控制和回滚机制
- 配置实时生效:配置变更后需要实时通知各个服务实例
- 配置安全性:敏感配置(如数据库密码)需要加密处理
分布式配置中心解决了这些问题,它提供:
- 配置的集中管理
- 配置的环境隔离
- 配置的版本控制
- 配置的动态刷新
- 配置的安全存储
Spring Cloud Config
Spring Cloud Config 是 Spring Cloud 提供的配置管理解决方案,它包含服务端(Config Server)和客户端(Config Client)两部分。
Spring Cloud Config Server
Config Server 是一个独立的微服务应用,它连接到配置仓库(如 Git 仓库)并为客户端提供配置信息。
配置服务器搭建
- 添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- 启用配置服务器
java
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
- 配置文件(application.yml)
yaml
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/your-username/your-config-repo
search-paths: '{application}'
default-label: main
# 如果是私有仓库
username: your-username
password: your-password
在上述配置中:
uri
: Git 仓库地址search-paths
: 搜索配置文件的路径模式,{application} 会被替换为客户端的应用名称default-label
: Git 仓库的默认分支
配置文件命名规则
Spring Cloud Config 支持以下命名规则的配置文件:
{application}-{profile}.yml
或.properties
{application}.yml
或.properties
application-{profile}.yml
或.properties
application.yml
或.properties
其中:
{application}
: 应用名称{profile}
: 环境标识,如 dev, test, prod
优先级从高到低,如 service-a-dev.yml
的优先级高于 service-a.yml
。
配置服务器 REST API
配置服务器暴露了以下 REST API:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
例如:
http://config-server:8888/service-a/dev
: 获取 service-a 应用的 dev 环境配置http://config-server:8888/service-a-dev.yml
: 以 YAML 格式获取配置
Spring Cloud Config Client
Config Client 是微服务应用,它在启动时连接到 Config Server 获取配置信息。
客户端配置
- 添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
- 创建 bootstrap.yml(或 bootstrap.properties)
yaml
spring:
application:
name: service-a
profiles:
active: dev
cloud:
config:
uri: http://config-server:8888
fail-fast: true # 连接配置中心失败时快速失败
注意:从 Spring Cloud 2020.0.0 版本开始,bootstrap 默认被禁用。如果使用的是这个版本或更高版本,需要添加
spring-cloud-starter-bootstrap
依赖,或在application.yml
中使用新的配置方式。
对于 Spring Cloud 2020.0.0 及以上版本,可以使用以下配置:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
或者,在 application.yml
中配置:
yaml
spring:
config:
import: optional:configserver:http://config-server:8888
application:
name: service-a
profiles:
active: dev
- 使用配置
客户端应用可以通过 @Value
注解、Environment
或者 @ConfigurationProperties
访问配置:
java
@RestController
@RefreshScope // 允许配置动态刷新
public class ConfigController {
@Value("${app.message}")
private String message;
@GetMapping("/message")
public String getMessage() {
return message;
}
}
配置动态刷新
当配置在配置服务器中更新后,客户端需要刷新才能获取新值。Spring Cloud Config 提供了多种配置刷新方式。
手动刷新
- 添加 Actuator 依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 配置 Actuator 端点
yaml
management:
endpoints:
web:
exposure:
include: refresh
- 使用
@RefreshScope
注解标记需要动态刷新的 Bean
java
@RefreshScope
@Component
public class ConfigProperties {
@Value("${app.message}")
private String message;
// getter and setter
}
- 手动调用刷新端点
当配置变更后,调用 /actuator/refresh
端点触发配置刷新:
bash
curl -X POST http://service-a:8080/actuator/refresh
使用 Spring Cloud Bus 实现自动刷新
手动刷新在服务实例多的情况下不实用,Spring Cloud Bus 可以实现配置的批量刷新。
- 添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
或者使用 Kafka:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
- 配置消息中间件连接
以 RabbitMQ 为例:
yaml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
- 配置 Actuator 端点
yaml
management:
endpoints:
web:
exposure:
include: refresh,bus-refresh
- 调用总线刷新端点
当配置变更后,只需调用任一服务实例的 /actuator/bus-refresh
端点,所有连接到同一消息总线的服务实例都会刷新配置:
bash
curl -X POST http://service-a:8080/actuator/bus-refresh
使用 Webhooks 实现自动刷新
更进一步,可以使用 Git 仓库的 Webhooks 触发配置自动刷新。这样当配置仓库发生变更时,会自动通知配置中心,进而通知各个服务更新配置。
- 配置 Config Server 暴露
/monitor
端点
yaml
management:
endpoints:
web:
exposure:
include: monitor
- 在 Git 仓库(如 GitHub)配置 Webhooks,URL 指向
http://config-server:8888/monitor
,内容类型设置为application/json
高级特性
配置加密与解密
Spring Cloud Config 支持配置值加密,保护敏感信息:
- 配置加密密钥(对称加密)
yaml
encrypt:
key: some-secret-key
或者使用非对称加密:
yaml
encrypt:
key-store:
location: classpath:keystore.jks
password: ${KEYSTORE_PASSWORD}
alias: config-server-key
secret: ${KEY_PASSWORD}
- 加密配置值
bash
curl -X POST http://config-server:8888/encrypt -d mypassword
这会返回加密后的值,如:AQAkGVlRz7YB0Td8zs+UZfm1eX8/t26K7xLTvzWV/Knm4qwYxiWbX8jQs2b/
- 在配置文件中使用加密值
yaml
spring:
datasource:
password: '{cipher}AQAkGVlRz7YB0Td8zs+UZfm1eX8/t26K7xLTvzWV/Knm4qwYxiWbX8jQs2b/'
客户端会自动解密使用 {cipher}
前缀的值。
配置的健康检查
Config Client 可以配置健康检查,确保与配置服务器的连接正常:
yaml
spring:
cloud:
config:
fail-fast: true # 连接配置中心失败时快速失败
retry: # 重试配置
initial-interval: 1000
max-attempts: 6
max-interval: 2000
multiplier: 1.1
配置属性重载顺序
Spring Cloud Config 有明确的属性加载优先级:
- 远程仓库(如 Git)的
application.yml
和其他配置文件 - 本地配置文件
bootstrap.yml
- 本地配置文件
application.yml
指定配置文件占位符
可以在客户端使用占位符从本地配置文件中获取配置:
yaml
spring:
cloud:
config:
uri: http://config-server:${config.port:8888}
备份配置
为保证配置中心不可用时应用仍能正常启动,可以采用备份配置:
- 使用配置客户端启动器的重试机制
- 在客户端本地保留最近一次成功的配置备份
- 使用本地文件系统作为备份的配置源
Spring Cloud Config 与服务发现集成
Config Server 可以注册到服务发现系统,客户端通过服务发现找到 Config Server:
- 在 Config Server 中添加服务发现依赖,如 Eureka Client:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 启用服务发现
java
@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
- 客户端配置使用服务发现查找 Config Server
yaml
spring:
cloud:
config:
discovery:
enabled: true
service-id: config-server
使用文件系统作为配置源
除了 Git 仓库,Spring Cloud Config 也支持使用本地文件系统作为配置源:
yaml
spring:
profiles:
active: native
cloud:
config:
server:
native:
search-locations: file:/config-repo
注意:使用 native
配置文件激活本地文件系统模式。
使用 Spring Cloud Config 的最佳实践
- 配置分层管理:将配置分为应用级、环境级和默认三层,利用继承关系减少重复配置
- 敏感配置加密:对数据库密码等敏感信息进行加密
- 版本控制:使用 Git 的版本控制能力,方便配置回滚
- 高可用配置中心:部署多个 Config Server 实例,避免单点故障
- 配置变更审计:利用 Git 的提交历史进行配置变更审计
- 环境隔离:使用不同分支或仓库严格隔离各环境配置
- 结合服务发现:Config Server 注册到服务注册中心,简化客户端配置
- 自动化刷新:使用 Spring Cloud Bus 实现配置的自动刷新
- 健康检查:启用健康检查,及时发现配置中心问题
- 合理的配置粒度:配置不要过粗或过细,保持合理的粒度
替代方案比较
除了 Spring Cloud Config,还有其他常用的分布式配置中心:
特性 | Spring Cloud Config | Nacos | Apollo | Consul |
---|---|---|---|---|
开发语言 | Java | Java | Java | Go |
配置存储 | Git/文件系统 | 内存/MySQL | MySQL | 内存/文件系统 |
配置格式 | YAML/Properties | YAML/Properties/JSON | Properties | KV |
配置推送 | 拉取为主,结合消息总线推送 | 实时推送 | 实时推送 | 实时推送 |
权限控制 | 基本支持 | 细粒度支持 | 细粒度支持 | 基本支持 |
版本控制 | 依赖 Git | 内置 | 内置 | 有限支持 |
配置审计 | 依赖 Git | 内置 | 内置 | 有限支持 |
配置回滚 | 依赖 Git | 支持 | 支持 | 有限支持 |
多环境 | 支持 | 支持 | 支持 | 有限支持 |
可视化控制台 | 无(需自行开发) | 有 | 有 | 有 |
Spring Cloud 集成 | 原生支持 | 通过 Spring Cloud Alibaba | 通过适配器 | 通过 Spring Cloud Consul |
总结
Spring Cloud Config 提供了一套完整的分布式配置管理解决方案,满足了微服务架构下配置集中管理的需求。它具有以下特点:
- 支持配置的集中管理和版本控制
- 提供配置的加密和解密功能
- 与 Spring Boot 生态系统无缝集成
- 支持配置的动态刷新,特别是与 Spring Cloud Bus 结合
- 提供多种配置存储方式,如 Git、文件系统等
在选择分布式配置中心时,应根据团队技术栈、功能需求和运维能力综合考虑。Spring Cloud Config 作为 Spring Cloud 生态的一部分,对于 Spring Boot 应用来说是一个很好的选择,尤其是当团队已经在使用 Git 进行配置管理时。