Skip to content

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: true

2.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: true

3. 动态配置刷新

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: 200

4. 配置加密

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.1

6.3 配置刷新端点

yaml
management:
  endpoints:
    web:
      exposure:
        include: refresh,busrefresh
bash
# 刷新单个服务配置
curl -X POST http://localhost:8080/actuator/refresh

# 刷新所有服务配置
curl -X POST http://localhost:8080/actuator/busrefresh

7. 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,common

7.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 ConfigGit 后端、配置刷新
Apollo携程 Apollo、配置管理

下一章将学习 Spring Cloud 熔断限流。