元OS 配置中心(Aegis.UMeta.ConfigCenter)
Aegis.UMeta.ConfigCenter 把元OS 配置中心(uos-config-center)上的配置项挂进 IConfiguration,业务代码继续用 IConfiguration["键"]、IOptionsMonitor<T>、ConfigManager.Get 取值,读取方式不变。配置中心上点「发布」后约 30 秒内应用自动拿到新值,不用重启进程。组件只读,不提供写配置能力。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | 元OS 配置中心 |
| 真实类库 | Aegis.UMeta.ConfigCenter |
| 最新版本 | 3.1.4-preview9 |
| 组件定位 | 元OS 配置中心(uos-config-center)只读配置源,挂进 IConfiguration 并支持发布后自动重读 |
| 引入方式 | NuGet 安装,Component.deps.json 声明 UMeta.ConfigCenter |
| 主要配置 | UosConfigCenter(根级配置节) |
| 核心能力 | 只读挂载、断网仍可启动(本地缓存 + 随包基线文件)、发布后约 30 秒热更新、Json / Yaml / Value 三种内容格式 |
| 典型配套 | 配置(Aegis.Configuration)、诊断组件(Aegis.Diagnostics) |
配置节是根级 UosConfigCenter,不是 UMeta:ConfigCenter。节名对齐服务名 uos-config-center。
什么时候要用它
适合场景:
- 配置放在元OS 配置中心上集中管理,同一产品的多个服务共享(应用名是产品粒度,如「医生站」;服务之间的差异用配置项名称区分)
- 现场可能连不上配置中心,应用仍要能带着随包的出厂配置启动
- 改配置不想重启进程:配置中心发布后约 30 秒内生效
- 业务代码已经在用
IConfiguration/IOptionsMonitor<T>/ConfigManager,不想换一套读取方式
不适合场景:
- 需要运行期写配置、把老配置迁移进来、或把首次读取的结果写回基线文件。这些都不在 v1 范围内,组件只读。需要演进的业务配置,直接使用 aims-config-sdk 按平台文档接入
- 还在用老 MetaOs 配置中心(
SettingCenter节)且没有迁移计划。继续用老组件Aegis.Configuration.ConfigCenter(deps 声明ConfigCenter),两者可以共存,见下文与老配置中心组件的共存
最小可运行路径
第一步:安装包
dotnet add package Aegis.UMeta.ConfigCenter
包基于 aims-config-sdk,私有 NuGet 源里已包含。
第二步:声明组件
Component.deps.json 的 Load 列表加一条:
{
"Components": {
"Load": [
"UMeta.ConfigCenter"
]
}
}
组件内置 Order -250,装配时自动排在所有读配置的组件之前,写在 Load 清单的什么位置都不影响顺序。
第三步:准备配置
appsettings.json 里声明应用名和要挂载的配置项:
{
"Aegis": {
"AppName": "医生站"
},
"UosConfigCenter": {
"Configs": [
{ "Name": "application", "BaselinePath": "ConfigCenterBaseline/application.json" },
{ "Name": "biz-settings", "BaselinePath": "ConfigCenterBaseline/biz-settings.json", "KeyPrefix": "Biz" },
{ "Name": "feature-flag", "BaselinePath": "ConfigCenterBaseline/feature-flag.txt", "Format": "Value", "Key": "Checkout:NewEnabled", "Optional": true }
]
}
}
三条声明对应三种典型用法:整份 JSON 拍平并入根、加 KeyPrefix 前缀隔离、纯文本值映射成单键。每个配置项都带一份随包基线文件(BaselinePath),配置中心连不上时应用用它启动。
第四步:按原方式取值
public class CheckoutOptions
{
public bool NewEnabled { get; set; }
}
public class CheckoutController(
IConfiguration configuration,
IOptionsMonitor<CheckoutOptions> monitor) : ControllerBase
{
[HttpGet("checkout")]
public IActionResult Get() => Ok(new
{
DictA = configuration["Biz:Dict:A"],
NewEnabled = monitor.CurrentValue.NewEnabled
});
}
上面的例子里,biz-settings 拍平加前缀后得到键 Biz:Dict:A,feature-flag 的内容映射成键 Checkout:NewEnabled,取值方式与本地 appsettings 完全一样。CheckoutOptions 绑定的就是 Checkout 节。
配置项说明(UosConfigCenter 节)
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Application | string | 回落 Aegis:AppName | 配置中心注册的应用名,产品/应用粒度(如「医生站」)。UosConfigCenter:Application 与 Aegis:AppName 都没配时启动失败 |
Server | string | 回落环境变量 CONFIG_CENTER_PATH,再回落 http://uos-config-center-svc:8080 | SDK API 地址。经网关接入须带 /uos-config-center 前缀;这不是 /setting_center 管理台地址 |
Namespace | string | 回落环境变量 NAMESPACE,再回落 default | 命名空间,灰度发布维度,运行期不切换 |
Token | string | 回落环境变量 CONFIG_CENTER_TOKEN | API Key。本期认证关闭,可留空 |
Interval | int | 5 | SDK 后台同步间隔(秒)。变更感知靠 SDK 每 30 秒一次的变更查询,与此值无关 |
StoragePath | string | .configs | SDK 本地磁盘缓存目录 |
AutoUpdate | bool | true | SDK 自动更新本地缓存 |
Configs | 数组 | 必填至少一项 | 要挂载的配置项清单,见下表 |
ReloadOnChange | bool | true | 收到配置中心变更后是否重读并触发 IConfiguration 重载 |
Configs 数组每项的字段:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Name | string | 必填 | 配置项名(configName),对应配置中心上该应用下的一个配置文件单元 |
BaselinePath | string | 建议必配 | 随包基线文件路径,读取链的最后一级。相对路径相对运行时工作目录 |
KeyPrefix | string | 无前缀 | 该份配置拍平后的键前缀;缺省直接并入根。多份配置含同名顶层键时用它避免互相覆盖 |
Format | string | 自动识别 | Json / Yaml / Value。自动识别规则:{ 或 [ 开头按 Json,含换行按 Yaml,否则按 Value |
Key | string | 同 Name | 仅 Value 格式生效:整份内容映射到的键名 |
Optional | bool | false | true = 该份读取完全失败时记警告跳过,不阻断启动;false = 首次加载失败直接抛错,应用起不来 |
连接参数的整体优先级:配置节里的显式配置 > 环境变量(CONFIG_CENTER_PATH / NAMESPACE / CONFIG_CENTER_TOKEN)> SDK 默认值。集群内部署时只注入环境变量即可用,什么都不配就是 http://uos-config-center-svc:8080 加 default 命名空间。
读一份配置的顺序与断网行为
SDK 读一份配置的顺序:
- 查进程内缓存
- 缓存没有就连远端服务,连接失败重试 5 次
- 远端仍拿不到,读本地磁盘缓存目录(默认
.configs) - 最后读随包基线文件(
BaselinePath指定的文件)
四级全部落空,该份配置读取失败。断网环境下单份配置大约 5 秒后落到基线文件继续启动;声明了多份配置时并行读取,启动耗时取决于最慢的那份。
Optional 字段决定失败后的表现:
Optional=false(缺省):首次加载失败抛AegisConfigurationException,应用不启动Optional=true:记一条警告,跳过该份,其余照常
内容解析失败(比如格式识别错了)不阻断启动,记警告跳过该份,配置项上用 Format 显式指定格式可以解决。
热更新行为
配置中心上点「发布」后,SDK 每 30 秒一次的变更查询会拿到新版本,组件把所有配置项整表重读,替换进 IConfiguration 并触发重载。ReloadOnChange 缺省开。重读失败时保留旧值,等下一次变更再试。
取值侧的表现:
| 取值方式 | 发布后表现 |
|---|---|
IConfiguration["键"] | 重载后读到新值 |
IOptionsMonitor<T>.CurrentValue | 下次取值即新值 |
ConfigManager.Get | 下次取值即新值 |
构造注入的 IOptions<T> | 启动时的快照,不会更新 |
要跟着热更新的配置,用 IOptionsMonitor<T> 取。
内容格式与键的形态
| 格式 | 拍平结果 | 示例 |
|---|---|---|
Json | 嵌套结构展开为「a:b:c」层级键 | {"Checkout":{"TimeoutMs":3000}} 变成键 Checkout:TimeoutMs |
Yaml | 同上,按 YAML 结构展开 | Checkout:\n TimeoutMs: 3000 变成键 Checkout:TimeoutMs |
Value | 整份内容 Trim 掉行尾空白后作为单个键的值 | 文件内容 true 映射为键 Checkout:NewEnabled 的值 true |
配了 KeyPrefix 的配置,所有键前面加前缀:KeyPrefix: "Biz" 时 Dict:A 变成 Biz:Dict:A。Value 格式用 Key 指定键名,缺省同 Name。
自定义扩展
多份配置的组合
一个应用挂多份配置是常规用法:主配置(JSON)并入根,业务配置加 KeyPrefix 隔离,开关类配置用 Value 单键。三份声明互不影响,合并按 Configs 数组的声明顺序。
手动挂载配置源
不走 Component.deps.json 装配、需要在构建宿主时自己挂配置源的场景,用扩展方法:
builder.Configuration.AddUMetaConfigCenter(new UMetaConfigCenterOptions
{
Application = "医生站",
Configs =
[
new UMetaConfigItemOptions { Name = "application", BaselinePath = "ConfigCenterBaseline/application.json" }
]
});
组件的自动装配内部走的也是这个入口。配置好以后业务读取方式不变。
Component.deps.json 声明与手动 AddUMetaConfigCenter 不要同时用,否则配置源会挂两份、同一份配置读两遍。自动装配已覆盖常规场景,手动挂载留给特殊的构建时机。
与老配置中心组件的共存
老组件 Aegis.Configuration.ConfigCenter(MetaOs)不受本组件影响,两者可以同时声明:
| 老组件 | 本组件 | |
|---|---|---|
| 类库 | Aegis.Configuration.ConfigCenter | Aegis.UMeta.ConfigCenter |
| deps 声明 | ConfigCenter | UMeta.ConfigCenter |
| 配置节 | SettingCenter | UosConfigCenter |
| 后端 | MetaOs 配置中心 | 元OS 配置中心(uos-config-center) |
两边声明的键都进 IConfiguration,键名撞车时后挂的来源覆盖先挂的。迁移期间两边各管各的配置项即可。
在 /diag 页面上看配置来源
装配了诊断组件(Aegis.Diagnostics)的应用,/diag 页面的「其它配置」分组会自动出现本组件挂进来的键值,值自动脱敏,不需要任何额外配置。排查「远端值到底进没进配置树」时直接看这里。
接入后怎么确认生效
- 启动横幅出现「配置中心源已挂载」信息,带 app、ns、server、configs 四项
IConfiguration["Biz:Dict:A"]这类键能读到配置中心上的值- 把配置中心停掉再启动应用:带基线文件的应用照常起来,值是基线文件内容;只有必填的那份(未配
Optional: true)连基线文件都读不到时,应用才起不来 - 配置中心上改值并发布,约 30 秒内
IOptionsMonitor<T>.CurrentValue拿到新值 /diag页面「其它配置」分组出现该来源的键值(自动脱敏)
常见问题
启动报「UosConfigCenter:Application 与框架键 Aegis:AppName 均未设置」
应用名两处都没配。补 UosConfigCenter:Application 或 Aegis:AppName,取其一。注意 Aegis:AppName 填产品名(如「医生站」),服务名(如「医生站对外API」)的约定键是 Aegis:ApplicationName,本组件不消费它。不需要配置中心的话,从 Load 列表移除 UMeta.ConfigCenter。
启动报「UosConfigCenter:Configs 为空」
声明了组件但一个配置项都没配。至少声明一项(Name + BaselinePath),或从 Load 列表移除组件。
启动抛 AegisConfigurationException,提示配置项读取失败
读取链四级全部落空(内存、远端、本地缓存、基线文件都拿不到)。按异常信息里的四步自查:
Server地址是 SDK API 地址,经网关接入要带/uos-config-center前缀,不是/setting_center管理台地址- 探一下服务端存活:
curl http://uos-config-center-svc:8080/health/liveness,应返回 200 - 确认该配置项已在配置中心上、且挂在本应用名下并发布
- 确认
BaselinePath指向的文件随包存在,相对路径相对运行时工作目录
配置中心发布了,应用里的值没变
先看取值方式:构造注入的 IOptions<T> 是启动快照,不会热更新,换成 IOptionsMonitor<T>。再等约 30 秒(SDK 的变更查询周期)。ReloadOnChange 配成 false 会把重读整个关掉。
能通过这个组件写配置吗
不能。v1 只读,基线引导写回、配置迁移、运行期写都不在范围内。需要演进的业务配置,直接使用 aims-config-sdk,按平台文档接入。
老配置中心(SettingCenter)还继续用吗
不受影响。Aegis.Configuration.ConfigCenter 照常工作,两边组件声明键不同(ConfigCenter 与 UMeta.ConfigCenter)、配置节不同(SettingCenter 与 UosConfigCenter),可以在同一个应用里共存,迁移期间各管各的配置项。
配套阅读
- 配置(Aegis.Configuration) — 统一配置读取底座,
ConfigManager的来源 - 诊断组件(Aegis.Diagnostics) —
/diag页面,「其它配置」分组在这里看配置来源键值 - Component.deps.json 组件清单 —
Load清单与组件 Order 排序规则