Skip to content
第 10 章 架构 ⏱ 11 分钟阅读

第 10 章:配置中心 ​

学习目标 ​

  • 理解配置中心解决的"配置分散"问题
  • 掌握 Nacos Config / Apollo / Spring Cloud Config
  • 学会动态配置刷新和灰度发布
  • 避免配置泄漏、配置覆盖的坑

一、为什么需要配置中心? ​

text
微服务时代
├── order-service
├── payment-service
├── inventory-service
└── ... 50 个服务

每个服务都有一份 application.yml
├── 数据库地址
├── Redis 地址
├── 第三方 API Key
└── 业务参数(超时时间、限流阈值)
java
// ❌ 痛点:改一个参数要重启 50 个服务
public class DbConfig {
    public static final String URL = "jdbc:mysql://192.168.1.10:3306/order_db";
    // 改 DB 要改代码 + 重新部署
}

二、Nacos Config 入门 ​

xml
<!-- 引入依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
yaml
# bootstrap.yml(优先级高于 application.yml)
spring:
  application:
    name: order-service
  cloud:
    nacos:
      config:
        server-addr: nacos:8848
        namespace: prod
        file-extension: yaml
        refresh-enabled: true
java
// 1. 静态配置
@Value("${db.url}")
private String dbUrl;

// 2. 动态配置(支持热更新)
@RestController
@RefreshScope                    // 关键注解
public class ThresholdController {
    @Value("${order.threshold:100}")
    private int threshold;

    @GetMapping("/threshold")
    public int getThreshold() {
        return threshold;
    }
}

⚠️ 坑 1:@Value 注入的字段改了不生效,因为没有被 @RefreshScope 包裹。Bean 级别的热更新。

三、命名空间与分组 ​

text
Nacos
├── Namespace(环境隔离)
│   ├── dev
│   ├── test
│   ├── staging
│   └── prod
└── Group(应用分组)
    ├── ORDER_GROUP
    ├── PAYMENT_GROUP
    └── COMMON_GROUP
yaml
# Data ID 命名:服务名-环境.后缀
# order-service-dev.yaml
# order-service-prod.yaml
spring:
  cloud:
    nacos:
      config:
        namespace: prod              # 命名空间
        group: ORDER_GROUP           # 分组
java
// 不同服务共享通用配置
@Configuration
@NacosConfigurationProperties(dataId = "common.yaml", group = "COMMON_GROUP")
public class CommonConfig {
    private String redisHost;
    private int redisPort;
}

四、Apollo 配置中心 ​

java
// 1. 客户端注解
@Service
public class InventoryService {
    @ApolloConfig
    private Config config;

    @Value("${inventory.stock.warning:10}")
    private int warningThreshold;
}

// 2. 监听变更
@Service
public class ThresholdListener {
    @ApolloConfigChangeListener
    public void onChange(ConfigChangeEvent event) {
        for (String key : event.changedKeys()) {
            ConfigChange change = event.getChange(key);
            log.info("配置变更:{} {} -> {}", key, change.getOldValue(), change.getNewValue());
        }
    }
}

五、配置加密 ​

yaml
# Nacos 配置(明文)
db:
  password: 123456          # ❌ 敏感信息
java
// 1. Nacos 配置加密 + 自定义解密
public class DecryptConfigListener implements Listener {
    @Override
    public void receiveConfigInfo(String configInfo) {
        // 加密值:ENC(base64(...))
        String decrypted = AESUtil.decrypt(configInfo);
    }
}

// 2. Jasypt 加密
@Configuration
public class EncryptConfig {
    @Bean
    public StringEncryptor encryptor() {
        PooledPBEStringEncryptor enc = new PooledPBEStringEncryptor();
        enc.setPassword("master-key");
        return enc;
    }
}

// 3. application.yml 引用
db:
  password: ENC(加密后的字符串)

⚠️ 坑 2:密钥(master-key)写进配置文件,等于没加密。密钥放环境变量或 K8s Secret,从外部注入。

六、配置灰度发布 ​

java
// 1. Nacos 灰度:指定 IP 生效
@NacosValue(value = "${order.threshold:100}", autoRefreshed = true)
private int threshold;

// 灰度规则:10.0.0.5 这台机器先试用新值
// 在 Nacos 控制台设置灰度 IP 列表
java
// 2. Apollo 灰度
GrayReleaseRule rule = new GrayReleaseRule();
rule.setAppId("order-service");
rule.setClusterName("default");
rule.setIp("10.0.0.5");
rule.setReleaseId("20240101-001");
grayReleaseManager.updateRule(rule);

七、配置版本与回滚 ​

text
配置历史
├── v1.0 阈值 100 → 订单成功率 95%
├── v2.0 阈值 500 → 订单成功率 99% ✅
└── v3.0 阈值 1000 → 订单成功率 92% ❌ 回滚到 v2.0
java
// 配置版本回滚
nacosClient.publishConfig(
    "order-service.yaml",
    "ORDER_GROUP",
    oldConfigValue              // 恢复成 v2.0 内容
);

⚠️ 坑 3:改配置前没记录旧值,出问题回滚需要查 git 历史。所有配置变更走 PR,自动记录 diff。

八、配置推送可靠性 ​

yaml
# Nacos 长轮询(默认 30s)
spring:
  cloud:
    nacos:
      config:
        refresh-enabled: true
        poll-timeout: 30000
java
// 监控配置变更
@EventListener
public void onConfigChange(ConfigChangeEvent event) {
    log.info("配置变更:{}", event.getKey());
    // 业务清理缓存、重新初始化连接池
    connectionPool.refresh();
}

本章小结 ​

组件特点
Nacos Config双栈,生态全,推荐
Apollo携程开源,审计完善
Spring Cloud ConfigSpring 官方,Git 后端
关键点建议
命名空间dev/test/staging/prod 隔离
敏感配置加密 + 密钥外部存储
灰度发布新配置先小范围生效
热更新@RefreshScope 包裹

动手练习 ​

  1. Nacos 部署:用 Docker 起 Nacos,创建 order-service-dev.yaml 试读取
  2. 动态刷新:写一个 @RefreshScope Bean,改 Nacos 配置观察值变化
  3. 配置加密:用 Jasypt 加密数据库密码,验证应用可以正常启动
  4. 灰度发布:开启灰度,指定一个 IP 优先使用新值,其他机器保持旧值

下一章:第 11 章:API 网关 →

本站基于 VitePress 构建 · 由 StackHub 团队维护