跳到主要内容

分布式配置中心设计

问题

如何设计分布式配置中心,实现配置的集中管理、动态刷新和灰度发布?

答案

为什么需要配置中心

问题传统方式配置中心
配置散落各服务本地文件统一管理
修改需重启改配置重启服务动态刷新
多环境管理手动维护多份环境隔离
灰度发布不支持灰度规则配置
配置审计变更历史记录

主流配置中心对比

特性NacosApolloSpring Cloud Config
开源方阿里巴巴携程Spring
配置管理
服务发现
实时推送长轮询 / gRPC长轮询 + 通知Git Webhook / Bus
灰度发布
多环境namespace + groupenv + clusterprofile + label
管理界面✅(更强大)❌(需额外开发)
配置回滚Git 回滚
选型建议
  • 已用 Nacos 做注册中心,配置中心也用 Nacos(统一技术栈)
  • 配置管理需求复杂(灰度、权限、审批),选 Apollo
  • 极简场景 / Spring 技术栈,选 Spring Cloud Config

配置中心架构

Nacos 配置中心

bootstrap.yml — Nacos 配置
spring:
application:
name: order-service
cloud:
nacos:
config:
server-addr: nacos:8848
namespace: dev # 环境隔离
group: ORDER_GROUP # 业务分组
file-extension: yaml
# 共享配置
shared-configs:
- data-id: common-db.yaml
group: SHARED
refresh: true
动态刷新配置
@RestController
@RefreshScope // 配置变更时重新注入
public class OrderController {

@Value("${order.timeout:30}")
private int orderTimeout; // 支持动态更新

// 或者使用 @ConfigurationProperties
@Autowired
private OrderProperties orderProperties;
}

// 监听配置变更事件
@Component
public class ConfigChangeListener {

@NacosConfigListener(dataId = "order-service.yaml", groupId = "ORDER_GROUP")
public void onConfigChange(String config) {
log.info("配置变更: {}", config);
// 刷新本地缓存、连接池等
}
}

Apollo 配置管理

Apollo 的配置层级:

Application → Environment → Cluster → Namespace
(dev/uat/prod) (机房) (配置集)
Apollo 使用
// 方式1:注解
@ApolloConfig
private Config config;

@ApolloConfigChangeListener
private void onChange(ConfigChangeEvent event) {
for (String key : event.changedKeys()) {
ConfigChange change = event.getChange(key);
log.info("Key: {}, Old: {}, New: {}",
key, change.getOldValue(), change.getNewValue());
}
}

// 方式2:API
String value = ConfigService.getAppConfig().getProperty("key", "default");

动态刷新原理

灰度配置发布

灰度策略:

  • 按 IP:指定灰度机器 IP
  • 按标签:给实例打标签(canary=true)
  • 按比例:10% → 50% → 100%

配置安全

策略说明
加密存储敏感配置(密码、密钥)加密存储,客户端解密
权限控制不同团队只能修改自己的 namespace
审批流程生产环境配置变更需审批
变更审计记录谁在什么时候改了什么
回滚能力支持一键回滚到历史版本

常见面试问题

Q1: 配置中心挂了怎么办?

答案

  • 本地缓存:客户端缓存最近一次拉取的配置到本地文件
  • 配置中心不可用时,使用本地缓存继续工作
  • 配置中心恢复后,自动重新连接并同步
  • Nacos / Apollo 都有本地快照机制

Q2: Nacos 的长轮询和 Apollo 的推拉结合有什么区别?

答案

  • Nacos 长轮询:客户端发起 HTTP 长轮询,服务端 hold 住请求(默认 29.5s),有变更立即返回
  • Apollo 推拉结合:客户端维护长连接 + 服务端推送变更通知 + 客户端定时拉取兜底
  • 两者都能做到秒级感知配置变更

Q3: 配置的优先级顺序是怎样的?

答案

Spring Boot 配置优先级(从高到低):

  1. 命令行参数
  2. 远程配置中心
  3. application-{profile}.yml
  4. application.yml
  5. @PropertySource 注解
  6. 默认值

详见 Spring Boot 配置管理

Q4: 如何做配置的多环境管理?

答案

以 Nacos 为例:

  • Namespace:环境隔离(dev / test / uat / prod)
  • Group:业务分组(ORDER_GROUP / PAY_GROUP)
  • DataId:具体配置文件(order-service.yaml)

不同环境的配置完全隔离,不会互相影响。参考 配置中心

相关链接