Spring Cloud 配置中心
1. 配置中心概述
1.1 什么是配置中心
配置中心是微服务架构中集中管理配置的服务,支持动态配置更新、环境隔离、配置版本管理。
1.2 配置中心功能
| 功能 | 说明 |
|---|---|
| 集中配置 | 统一管理所有服务配置 |
| 动态更新 | 配置实时刷新 |
| 环境隔离 | dev/test/prod 环境隔离 |
| 版本管理 | 配置历史版本 |
| 灰度发布 | 按比例推送配置 |
2. Nacos 配置中心
2.1 添加依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2023.0.1.0</version>
</dependency>2.2 配置加载
yaml
# bootstrap.yml
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: dev
group: DEFAULT_GROUP
file-extension: yaml
prefix: ${spring.application.name}
refresh-enabled: true2.3 配置文件结构
Nacos 配置管理:
namespace: dev
├── group: DEFAULT_GROUP
│ ├── user-service.yaml # 公共配置
│ ├── user-service-dev.yaml # 开发环境
│ ├── user-service-test.yaml # 测试环境
│ ├── user-service-prod.yaml # 生产环境
│ ├── common.yaml # 公共配置
│ └── redis.yaml # Redis 配置2.4 多配置文件加载
yaml
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
shared-configs:
- data-id: common.yaml
group: DEFAULT_GROUP
refresh: true
- data-id: redis.yaml
group: DEFAULT_GROUP
refresh: true
extension-configs:
- data-id: datasource.yaml
group: DEFAULT_GROUP
refresh: true
- data-id: rabbitmq.yaml
group: DEFAULT_GROUP
refresh: true3. 动态配置刷新
3.1 @RefreshScope
java
@RestController
@RefreshScope
public class ConfigController {
@Value("${app.config.name:default}")
private String configName;
@Value("${app.config.max-connections:100}")
private int maxConnections;
@Value("${app.feature.enabled:false}")
private boolean featureEnabled;
@GetMapping("/config")
public Map<String, Object> getConfig() {
return Map.of(
"configName", configName,
"maxConnections", maxConnections,
"featureEnabled", featureEnabled
);
}
}
@Configuration
@RefreshScope
public class DynamicConfig {
@Value("${app.thread-pool.core-size:10}")
private int coreSize;
@Value("${app.thread-pool.max-size:50}")
private int maxSize;
@Bean
public ThreadPoolExecutor dynamicThreadPool() {
return new ThreadPoolExecutor(
coreSize,
maxSize,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100)
);
}
}3.2 配置变更监听
java
@Component
public class ConfigChangeListener {
@NacosConfigListener(dataId = "user-service.yaml", groupId = "DEFAULT_GROUP")
public void onConfigChange(String newConfig) {
log.info("配置变更: {}", newConfig);
}
@NacosConfigListener(dataId = "user-service.yaml")
public void onConfigChange(ConfigChangeEvent event) {
for (ConfigChangeItem item : event.getChangeItems()) {
log.info("配置变更: {} = {} -> {}",
item.getKey(),
item.getOldValue(),
item.getNewValue());
}
}
}3.3 配置类绑定
java
@ConfigurationProperties(prefix = "app")
@RefreshScope
public class AppConfig {
private String name;
private String version;
private Feature feature = new Feature();
private ThreadPool threadPool = new ThreadPool();
public static class Feature {
private boolean enabled;
private String level;
}
public static class ThreadPool {
private int coreSize = 10;
private int maxSize = 50;
private int queueCapacity = 100;
}
// getters and setters
}
@Configuration
@EnableConfigurationProperties(AppConfig.class)
public class AppConfigEnable {
}yaml
app:
name: user-service
version: 1.0.0
feature:
enabled: true
level: high
thread-pool:
core-size: 20
max-size: 100
queue-capacity: 2004. 配置加密
4.1 添加依赖
xml
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>4.2 配置加密
yaml
jasypt:
encryptor:
password: ${JASYPT_PASSWORD}
algorithm: PBEWithMD5AndDES
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: ENC(加密后的密码)4.3 加密工具
java
@Service
public class EncryptionService {
@Autowired
private StringEncryptor encryptor;
public String encrypt(String plainText) {
return encryptor.encrypt(plainText);
}
public String decrypt(String encryptedText) {
return encryptor.decrypt(encryptedText);
}
}5. 配置灰度发布
5.1 灰度配置
java
@Configuration
public class GrayConfig {
@Bean
@ConditionalOnProperty(name = "app.gray.enabled", havingValue = "true")
public GrayFilter grayFilter() {
return new GrayFilter();
}
}
@Component
public class GrayConfigListener {
@NacosConfigListener(dataId = "gray-config.yaml")
public void onGrayConfigChange(ConfigChangeEvent event) {
ConfigChangeItem item = event.getChangeItem("app.gray.percentage");
if (item != null) {
int percentage = Integer.parseInt(item.getNewValue());
GrayConfigManager.setPercentage(percentage);
}
}
}
public class GrayConfigManager {
private static volatile int percentage = 0;
public static void setPercentage(int value) {
percentage = value;
}
public static int getPercentage() {
return percentage;
}
public static boolean isGrayUser(String userId) {
int hash = Math.abs(userId.hashCode());
return (hash % 100) < percentage;
}
}6. Spring Cloud Config
6.1 配置服务器
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);
}
}yaml
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/myorg/config-repo
search-paths: '{application}'
default-label: main
username: ${GIT_USERNAME}
password: ${GIT_PASSWORD}6.2 配置客户端
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>yaml
# bootstrap.yml
spring:
application:
name: user-service
profiles:
active: dev
cloud:
config:
uri: http://config-server:8888
name: ${spring.application.name}
profile: ${spring.profiles.active}
label: main
fail-fast: true
retry:
initial-interval: 1000
max-attempts: 6
max-interval: 2000
multiplier: 1.16.3 配置刷新端点
yaml
management:
endpoints:
web:
exposure:
include: refresh,busrefreshbash
# 刷新单个服务配置
curl -X POST http://localhost:8080/actuator/refresh
# 刷新所有服务配置
curl -X POST http://localhost:8080/actuator/busrefresh7. Apollo 配置中心
7.1 添加依赖
xml
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.1.0</version>
</dependency>7.2 Apollo 配置
yaml
app:
id: user-service
apollo:
meta: http://apollo-config-server:8080
cluster: default
namespace: application
autoUpdateInjectedSpringProperties: true
bootstrap:
enabled: true
namespaces: application,common7.3 配置使用
java
@Configuration
@EnableApolloConfig
public class ApolloConfig {
@Bean
public Config config() {
return ConfigService.getAppConfig();
}
}
@RestController
public class ApolloController {
@Value("${app.config.name:default}")
private String configName;
@ApolloConfig
private Config config;
@GetMapping("/config")
public Map<String, Object> getConfig() {
return Map.of(
"configName", configName,
"allConfig", config.getPropertyNames()
);
}
@ApolloConfigChangeListener
public void onChange(ConfigChangeEvent changeEvent) {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
log.info("配置变更: {} = {} -> {}",
key,
change.getOldValue(),
change.getNewValue());
}
}
}8. 配置最佳实践
8.1 配置分层
配置优先级(从高到低):
1. 命令行参数
2. 环境变量
3. 配置中心(application-{profile}.yaml)
4. 配置中心(application.yaml)
5. 本地配置(application-{profile}.yaml)
6. 本地配置(application.yaml)8.2 敏感配置
yaml
# 敏感配置使用环境变量或加密
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}8.3 配置验证
java
@Configuration
@Validated
@ConfigurationProperties(prefix = "app")
public class ValidatedConfig {
@NotBlank
private String name;
@Min(1)
@Max(100)
private int maxConnections;
@Pattern(regexp = "^[a-z]+$")
private String environment;
// getters and setters
}9. 小结
本章学习了 Spring Cloud 配置中心的核心内容:
| 内容 | 要点 |
|---|---|
| Nacos 配置 | 配置加载、多文件、动态刷新 |
| 配置刷新 | @RefreshScope、配置监听 |
| 配置加密 | Jasypt、敏感信息保护 |
| 灰度发布 | 灰度配置、灰度规则 |
| Spring Cloud Config | Git 后端、配置刷新 |
| Apollo | 携程 Apollo、配置管理 |
下一章将学习 Spring Cloud 熔断限流。