--- tags: [microservice, config-management, nacos, apollo, spring-cloud-config] create time: 2026-05-05 --- # 配置管理 ## 概述 当服务实例数以百计时,手动管理配置是不可想象的。配置中心提供 **集中化、动态化、版本化** 的配置管理能力。 > [!question] 引出配置中心的必要性 > 假设你的 50 个服务实例都要连同一个数据库。现在需要把数据库密码从 `password1` 改为 `password2`,你会怎么改?登录每台机器改配置文件?滚动重启所有 Pod?还是……有更好的办法? ## 核心价值 ```mermaid flowchart LR Dev["开发/运维"] --> CC[(配置中心)] CC -->|热更新推送| S1[Service A] CC -->|热更新推送| S2[Service B] CC -->|热更新推送| S3[Service C] CC -.->|版本管理| V1[v1.0 历史配置] CC -.->|版本管理| V2[v1.1 当前配置] ``` | 能力 | 说明 | |------|------| | **动态刷新** | 修改配置后立即生效,无需重启 | | **环境隔离** | dev / test / prod 配置分离 | | **版本管理与回滚** | 每次变更有迹可循,一键回滚 | | **权限控制** | 敏感配置(密钥、Token)按角色隔离 | | **配置审计** | 记录谁在什么时候改了什么 | ## 配置分层模型 ```mermaid graph TB subgraph "配置优先级(低 → 高)" Base["Base 基线配置
各项目共享的默认值"] App["应用级配置
每个服务的专属配置"] Env["环境级配置
dev/test/prod 差异"] Instance["实例级配置
单节点调优参数"] end style Base fill:#e3f2fd style App fill:#fff3e0 style Env fill:#fce4ec style Instance fill:#e8f5e9 ``` **典型配置项分层**: | 层级 | 示例 | 修改频率 | |------|------|---------| | 基线配置 | Redis 集群地址、公共超时时间 | 极低 | | 应用配置 | 线程池大小、日志级别 | 低 | | 环境配置 | DB 连接串、Feature Flag | 中 | | 实例配置 | 单机限流阈值、调试开关 | 高 | ## Nacos Config 示例 ```go // 动态监听配置变更 configClient, _ := clients.NewConfigClient(value_map.NewValueMap(map[string]any{ "serverConfig": sc, })) content, _ := configClient.GetConfig(config_param.GetConfigParam{ DataId: "order-service.yaml", Group: "DEFAULT_GROUP", }) // 监听配置变化——Nacos 推送更新回调 configClient.ListenChange(config_param.ListenChangeParam{ DataId: "order-service.yaml", Group: "DEFAULT_GROUP", Callback: func(content string) { fmt.Println("配置更新了:", content) // 重新加载配置... ReloadConfig(content) }, }) ``` ### 配置文件的命名规范 推荐格式:`{service-name}.{environment}.yaml` | 服务名 | 环境 | Data ID | |--------|------|---------| | order-service | dev | `order-service.dev.yaml` | | order-service | prod | `order-service.prod.yaml` | | user-service | prod | `user-service.prod.yaml` | ## Apollo vs Nacos Config 对比 | 维度 | Apollo (携程) | Nacos Config (阿里) | Spring Cloud Config | |------|--------------|---------------------|--------------------| | **界面体验** | Web UI 完善,操作直观 | 较好 | 需自建 | | **发布流程** | 支持审核、灰度、回滚 | 基础发布+回滚 | 依赖 Git 工作流 | | **配置粒度** | 应用/Cluster/Namespace 多维 | Service/Group | File-based | | **性能** | AP 模型,延迟 < 1s | AP 模型,延迟 < 1s | 读取 Git,延迟稍高 | | **生态集成** | 适合 Java/Spring 体系 | Java + Go + Python 等 | 仅 Spring 生态 | | **适用场景** | 大型企业,多团队协同 | 中小团队快速落地 | 纯 Spring 项目 | ## K8s ConfigMap & Secret 纯 K8s 环境内的原生方案: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: order-service-config data: application.yaml: | server: port: 8080 datasource: url: jdbc:mysql://db-host:3306/orders username: ${DB_USERNAME} password: ${DB_PASSWORD} --- apiVersion: v1 kind: Secret metadata: name: order-service-secrets type: Opaque stringData: DB_USERNAME: "app_user" DB_PASSWORD: "s3cret_p@ss" ``` 注入到容器: ```yaml envFrom: - configMapRef: name: order-service-config - secretRef: name: order-service-secrets ``` > [!warning] K8s 原生方案的局限 > - 修改 ConfigMap 后 Pod 不会自动重载配置(需配合 Sidecar 或手动触发 reload) > - 没有版本管理和灰度发布能力 > - **建议**:简单项目用 K8s ConfigMap,复杂场景上 Apollo/Nacos ## 敏感信息处理 > [!danger] 安全红线 > **永远不要**在代码仓库中硬编码密码、API Key、私钥等敏感信息。 ```mermaid flowchart LR Dev["开发者本地"] -->|"K8s Secret / Vault"| Store["加密存储"] Store -->|"运行时解密"| Runtime["运行时的环境变量"] Runtime --> App["应用程序"] Audit["审计系统"] -.->|"只读访问"| Store ``` **推荐方案**: - **K8s Secret** — 小型集群内使用(base64 编码,非加密,配合 EncryptionConfiguration 增强) - **HashiCorp Vault** — 企业级密钥管理,动态秘钥、自动轮换 - **云厂商 KV 服务** — AWS Secrets Manager / 阿里云 KMS / 腾讯云 SecretManager ## 关联笔记 - [[02-服务治理/服务发现/README]] — Nacos 同时提供服务发现和配置管理 - [[05-部署运维/Kubernetes/README]] — ConfigMap/Secret 是 K8s 的配置注入方式