Appearance
.NET 配置系统架构实践
在复杂的业务系统中,配置管理需要同时兼顾 安全性(如数据库密码不能泄露)和 灵活性(如业务开关需实时调整)。本文推荐一种成熟的“混合配置策略”。
1. 混合配置策略 (Hybrid Strategy)
我们将配置按性质分为两个层级,采用不同的存储和管理方式:
| 层级 | 存储位置 | 适用内容 | 变更生效 | 安全性 |
|---|---|---|---|---|
| L1 静态配置 | .env / appsettings.json | 基础设施连接串、第三方 API 密钥、不可变环境变量。 | 需重启服务 | 高(环境变量/私有文件) |
| L2 动态配置 | 数据库 (SysConfig 表) | 业务规则开关、网站基本信息、积分比例、上传限制。 | 实时生效 | 中(数据库存储,需脱敏) |
2. 静态配置:Options 模式
对于 L1 静态配置,推荐全面采用 ASP.NET Core 的强类型 Options 模式,而不是散落在各处的 Configuration["Key"]。
2.1 核心优势
- 强类型检查:在编译期发现拼写错误。
- 解耦:业务代码只依赖配置模型,不关心配置存放在 JSON 还是环境变量中。
- 验证:支持使用
DataAnnotations对配置项进行有效性校验。
2.2 实现模式
- 定义模型:在
Core/Options下创建配置类。 - 注册绑定:在启动代码中使用
services.Configure<TOptions>(Configuration.GetSection("SectionName"))。 - 注入使用:在服务中注入
IOptions<TOptions>(或IOptionsMonitor以支持热加载)。
3. 动态配置:数据库 JSON 方案
对于 L2 动态配置,为了平衡扩展性与性能,推荐使用“Key-Value (JSON)”结构存储。
3.1 数据库设计
使用一张简单的 SysConfig 表,包含 Type (Key) 和 JsonData (Value) 两个核心字段。这种设计类似 NoSQL,新增配置业务时无需修改表结构。
3.2 访问与缓存策略
- 读取流程:优先查询分布式缓存(Redis)-> 缓存未命中则查数据库 -> 反序列化为强类型 DTO -> 回填缓存。
- 写入流程:保存到数据库 -> 立即清除或更新对应的 Redis 缓存。
- 懒迁移 (Lazy Migration):在架构演进过程中,如果读取新版配置失败,可以尝试从旧版大一统的配置块中提取并自动迁移。
4. 安全与脱敏规范
配置系统的安全性至关重要,必须遵守以下红线:
- Secrets 分离:所有的敏感密钥(AccessKey、Password、Token)严禁存入数据库。必须存储在服务器本地环境变量或受保护的
.env文件中。 - 前端掩码:管理后台获取配置的接口在返回数据时,对于敏感字段应进行掩码处理。
- 错误做法:返回
AliyunSecret: "bz82..."。 - 正确做法:返回
HasAliyunSecret: true,前端仅显示“已配置”标识,不显示明文。
- 错误做法:返回
- 配置注入检查:应用启动时应检查关键配置是否缺失,若缺失则快速失败(Fail-Fast)。
5. 开发最佳实践清单
- [ ] 按领域拆分:不要把所有配置塞进一个巨大的
AppConfig,应按业务域拆分为SiteConfig,MemberConfig,StorageConfig等。 - [ ] 默认值保护:在配置 DTO 的属性中设置合理的默认值,防止数据库记录丢失导致应用崩溃。
- [ ] 描述信息:使用
[Display(Name = "...")]特性标注配置项的业务含义,方便后台自动生成表单。 - [ ] 版本兼容:当修改配置结构时,应考虑向后兼容性,或者提供迁移工具。
