Nacos Config 动态配置规范深度解析:资源身份、查询链、灰度发布与缓存一致性
【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos
本篇指南基于 Nacos 仓库specs/zh-cn/config/config-spec.md顶层规范,完整覆盖 Config 领域的定位边界、资源身份模型、六大设计原则、接口面划分,以及发布/查询、监听订阅、灰度发布、持久化 Dump、一致性可见性与容量运维等全部核心契约,并结合config模块源码(常量定义与 v3 Controller)印证各接口路径的真实实现,帮助读者建立从规范条款到代码落地的完整认知,从而正确设计配置接入、灰度方案与集群运维策略。
1. Config 的定位与领域边界
Nacos Config 是一个动态配置领域:以持久化资源的形式存储配置内容,并提供发布、查询、订阅分发、灰度发布、删除、历史、导入、导出、克隆、容量和运维诊断等完整的生命周期能力(见 config-spec.md)。
规范特别强调 Config 的“不是什么”:
- Config 是 Nacos 的一级领域,它不是通用文档库、对象存储、密钥管理系统、服务发现模型或 AI 资源模型;
- Config不拥有服务发现、服务实例生命周期或健康检查,这些属于 Naming 领域;
- AI 资源使用的存储兼容映射,不应让 AI 资源在新规范中变成普通 Config 资源;
- 配置加密通过插件保护内容,但 Config 不是完整的密钥生命周期或 KMS 领域;
appName、desc、configTags、type、use、effect、schema等元数据不改变资源身份;- 灰度发布状态是 Config 资源的从属状态,不应创建第二套顶层 Config 身份。
这一边界定义决定了后文所有能力(发布、监听、灰度、容量)都围绕同一个资源身份展开,而不是各自为政。
2. 资源身份:namespaceId -> groupName -> dataId
Config 采用微服务资源层次作为唯一标识:
namespaceId -> groupName -> dataId具体字段语义在 Config 资源规范中定义:
| 字段 | 含义 | 说明 |
|---|---|---|
namespaceId | 配置所属 namespace。 | 请求中的空值或缺省值会被归一化为默认 namespace id,当前为public。底层存储代码中仍可能称为tenant/tenantId,但当前模型不要求为空 tenant 与public保留重复的默认 namespace 记录。 |
groupName | namespace 内的业务分组。 | 新公开规范和 HTTP v3 表单使用groupName;底层 Config 模型和兼容 API 仍可能将该值称为group。 |
dataId | 配置资源名。 | dataId就是 Config 的resourceName。 |
三条关键约束值得重点理解:
- 身份字段是稳定的。修改
namespaceId、groupName或dataId表示新资源、克隆、导入或删除后重建,而不是普通元数据更新。 - 存储 ID 不是全局资源令牌。即使管理 API 或 SDK 允许通过存储 ID 批量选择配置,操作也必须受请求中归一化后的
namespaceId约束;存储 ID 不能绕过 namespace 身份。 - 存储 ID 序列化规则。存储 ID 出现在 JSON 响应中时,必须序列化为十进制字符串而非 JSON number,避免无法安全表示 64 位整数的客户端丢失精度。同时,当前管理 API 中接受存储 ID(
ids、configId)仅属于兼容行为,已被标记为废弃,后续将迁移到以namespaceId、groupName、dataId身份元组为基础的选择模型。
2.1 内容与版本字段
| 字段 | 含义 |
|---|---|
content | 黑盒配置正文,以文本内容存储,使用配置的持久化编码;Config 不操作正文内部的业务配置项。 |
md5 | 内容摘要,用于监听变更检测和 CAS 发布。 |
encryptedDataKey | 加密配置使用的受保护密钥材料,普通配置为空。 |
type | 配置内容类型,合法值为properties、xml、json、text、html、yaml、toml、unset;发布时非法输入会归一化为text。 |
元数据字段(appName、desc、configTags、use、effect、schema、srcUser/srcIp、createTime/modifyTime)均不属于身份字段。加密配置通过cipher-{algorithm}-的 dataId 约定识别(详见 配置加密插件规范),Config 领域负责存储处理后的内容与encryptedDataKey,算法选择与加解密操作属于加密插件。
2.2 校验规则与字段限制
单资源操作必须包含完整身份字段:dataId不能为空、groupName不能为空、仅当接口支持默认 namespace 处理时namespaceId可以省略。公开 Config 名称应只包含字母、数字、_、-、.和:。
当前字段限制:
| 字段 | 限制 |
|---|---|
namespaceId | 提供时最长 128 字符。 |
| tag | 最长 16 字符。 |
configTags | 最多 5 个 tag,每个 tag 最长 64 字符。 |
desc | 最长 128 字符。 |
use/effect | 最长 32 字符。 |
type | 最长 32 字符。 |
schema | 最长 32768 字符。 |
content | 不得超过配置的maxContent;容量检查可能施加更小的 max-size 策略。 |
此外,实现代码可以根据身份字段派生内部Group Key,用于缓存、监听、dump 和模糊订阅状态;该派生 key 是纯实现细节,新 API 或 SDK 契约中应继续使用规范化的公开字段。
3. 六大设计原则
顶层规范(config-spec.md)第 4 节定义了六条设计原则,这是理解整个 Config 领域行为的基础。
3.1 配置内容是黑盒
Config 将content作为黑盒整体处理:Nacos 只负责配置资源的生命周期,不解析、不合并、不做局部更新,也不围绕配置文件内部的某个业务配置项定义行为。type字段只描述内容类型用于展示和响应处理,不表示 Nacos 拥有内容内部的业务 schema。如果部署场景必须感知具体内部配置项(校验、转换或触发副作用),应通过扩展或下游系统自行处理。
3.2 持久化为源,运行时走缓存
Config 内容必须持久化保存;运行时读取通过 Config 缓存和本地 dump 文件提供,避免高频客户端查询和变更检查依赖大范围数据库查询。持久化层是可靠数据源,本地 dump 缓存是服务端查询和恢复层,必须在启动阶段和变更事件后从持久化数据刷新。
3.3 以 md5 表达内容版本
md5是内容版本标识,承担两个职责:
- 监听变更检测:监听时比较客户端持有的 md5 与服务端状态,不一致则提示客户端重新查询;
- CAS 发布:比较请求携带的
casMd5与已存储 md5,匹配后才允许更新,不匹配即资源冲突,不能覆盖已存储配置。
3.4 变更推送只是提示
变更推送只通知客户端某个资源可能发生变化,推送内容不能视为权威配置内容。客户端收到变更通知后必须再次查询对应 Config 资源。这一原则在后文监听与一致性章节中会反复出现。
3.5 运行面与管理面分离
- 运行时客户端:查询已知配置,监听已知配置或模式匹配的配置;
- 管理能力:大范围列表、搜索、导入、导出、克隆、监听诊断、历史、容量、指标和本地缓存操作,应通过 Admin API、Console API 或 Maintainer SDK 暴露。
运行时客户端连接、listener recovery、snapshot 和 failover 行为由 客户端运行时规范定义。
3.6 横切能力通过扩展接入
Config 可集成扩展机制,但领域归属不转移:
| 关注点 | 规则 |
|---|---|
| 加密 | Config 拥有内容身份和持久化;加密算法由 配置加密插件规范定义。 |
| 配置变更通知 | Config 拥有 事件分发与 NotifyCenter 规范定义的本地变更事件;外部回调由 配置变更插件规范定义。 |
| 数据源方言 | Config 拥有 repository 语义;SQL 方言由 数据源方言插件规范定义。 |
| 鉴权 | Config API 和 gRPC handler 使用SignType.CONFIG,遵循 鉴权与权限规范。 |
| Control | 高频发布、查询、监听、推送和模糊订阅流程应暴露稳定的 Control 点,遵循 Control 插件规范。 |
4. 接口面:规范定义与源码印证
顶层规范将 Config 的接口面划分为六类:
| 接口面 | 范围 |
|---|---|
| HTTP Open API | /v3/client/cs/config面向自定义 HTTP 客户端查询单个配置;不提供 HTTP 长轮询或大范围管理能力。 |
| HTTP Admin API | /v3/admin/cs/*提供配置 CRUD、列表/搜索、历史、监听诊断、容量、指标和运维操作。 |
| gRPC API | 提供运行时查询、兼容发布、兼容删除、精确监听、模糊订阅和服务端推送消息,参见 gRPC API 规范。 |
| Client SDK | 通过ConfigService面向运行时应用提供查询、监听、本地快照、filter 和兼容写入方法,参见 SDK 规范。 |
| Maintainer SDK | 通过ConfigMaintainerService等服务提供管理类接入。 |
| Console API | 面向 UI 的管理流程;可以调整展示形态,但不能重新定义 Config 语义。 |
在源码中,这些路径全部集中在 Constants.java 中定义,例如:
CONFIG_V3_CLIENT_API_PATH = "/v3/client/cs/config"(Constants.java#L156);BASE_ADMIN_V3_PATH = "/v3/admin/cs",派生出CONFIG_ADMIN_V3_PATH、HISTORY_ADMIN_V3_PATH、LISTENER_CONTROLLER_V3_ADMIN_PATH、CAPACITY_CONTROLLER_V3_ADMIN_PATH、METRICS_CONTROLLER_V3_ADMIN_PATH、OPS_CONTROLLER_V3_ADMIN_PATH等。
而各路径到具体控制器的映射在config模块的 v3 controller 包中一一对应,与规范声明的接口面完全吻合:
| 控制器 | 绑定路径 | 职责 |
|---|---|---|
| ConfigOpenApiController.java | /v3/client/cs/config | Open API 运行时单配置查询 |
| ConfigControllerV3.java | /v3/admin/cs/config | 配置 CRUD、列表、导入/导出/克隆 |
| HistoryControllerV3.java | /v3/admin/cs/history | 历史列表与详情 |
| ListenerControllerV3.java | /v3/admin/cs/listener | 监听诊断 |
| CapacityControllerV3.java | /v3/admin/cs/capacity | 容量查询与更新 |
| MetricsControllerV3.java | /v3/admin/cs/metrics | 指标查询 |
| ConfigOpsControllerV3.java | /v3/admin/cs/ops | 本地缓存 dump、日志级别、Derby 运维等 |
从源码结构看,/v3/admin/cs/*之下按能力拆分成独立 Controller 的组织方式,正是“运行面与管理面分离”原则在代码层的具体体现。
5. 发布与查询:从 CAS 到运行时查询链
Config 发布与查询规范定义了完整的发布/删除/查询/列表/导入导出克隆语义。
5.1 发布行为
发布正式 Config 会写入由namespaceId + group + dataId标识的资源。发布过程依次执行:
- 校验身份、内容、tag、元数据、namespace 和容量限制;
- 将空 namespace 归一化为默认 namespace id;
- 将非法配置
type归一化为text; - 当 dataId 匹配加密插件且请求未提供
encryptedDataKey时,对内容进行加密; - 根据请求字段写入正式配置或灰度配置版本;
- 记录持久化 trace 数据;
- 写入成功后发布 Config 变更事件(遵循 事件分发与 NotifyCenter 规范)。
CAS 发布必须比较请求携带的casMd5与已存储 md5;md5 不匹配表示资源冲突,不能覆盖已存储配置。且 CAS 失败不得发布变更事件(一致性规范第 3 节进一步约束了这一点)。
5.2 删除语义
- 删除正式 Config 会移除
namespaceId + group + dataId标识的资源,记录删除 trace,并发布变更事件;删除灰度配置只移除指定灰度版本。 - 兼容接口允许删除不存在的配置表现为成功,但新的管理流程不应把这种结果展示为该资源曾经存在。
- 按存储 ID 批量删除属于管理操作:请求必须携带或默认出归一化后的
namespaceId,实现只能删除该 namespace 内匹配的 ID;不存在的 ID 或其他 namespace 的 ID 可以跳过,但不得删除其他 namespace 的配置。
5.3 运行时查询链
运行时查询使用 Config 查询链,默认链路为:
entry/cache lock -> content type wrapper -> gray rule match -> special tag not-found handling -> formal config fallback有效语义顺序为:
- 归一化 namespace,并按
dataId + group + namespace查找缓存项; - 缓存项不存在,返回 config-not-found;
- 缓存项正在 dump 或被写锁修改,返回 query conflict,由客户端重试;
- 用请求标签匹配灰度规则(例如客户端 IP 和 tag);
- 命中灰度规则,返回命中的灰度内容、md5、
encryptedDataKey、最后修改时间、配置类型和灰度元数据; - 请求显式指定了特殊 tag 但没有命中 tag 灰度,返回 tag-specific not-found;
- 否则返回正式配置内容、md5、
encryptedDataKey、最后修改时间和配置类型; - 根据配置类型解析响应 content type,默认使用 text。
运行时查询必须使用缓存和 dump 内容,而不是大范围持久化查询——这正是设计原则 3.2 的落地。
5.4 管理查询、列表搜索与导入导出克隆
- Admin 查询面向管理用户返回配置详情;存储的加密配置会先解密内容,再返回详情对象。运行时查询响应则可能包含加密后的内容和
encryptedDataKey,客户端侧解密属于加密插件链路。 - 列表与搜索是管理操作,可对
dataId、groupName、namespaceId、appName、configTags、type和内容详情做精确或模糊检索。搜索必须受队列、线程数、容量和等待时间控制,避免大范围管理查询影响运行时查询和监听链路(Executor 边界由 任务执行规范定义)。 - 导入、导出与克隆:导出打包配置内容和元数据;导入要求元数据和内容互相匹配、应用请求指定的同名配置策略,并为成功写入发布变更事件;克隆将选中配置复制到目标 namespace,可选择目标 group 或 dataId。导入导出必须保留配置类型、描述、应用名、group、dataId、内容和加密语义。克隆的源配置 ID 只能在归一化后的源 namespace 内解析;缺省源 namespace 时默认等于目标 namespace,以保持同 namespace 克隆兼容。
接口层面的差异点:
| 接口面 | 规则 |
|---|---|
| HTTP Open API | 通过/v3/client/cs/config查询单个已知配置,不提供 HTTP 监听或大范围管理行为。 |
| HTTP Admin API | CRUD、元数据、列表/搜索、导入、导出、克隆、beta 查询/删除、监听、容量、指标和运维使用/v3/admin/cs/*;Admin 克隆中namespaceId表示目标 namespace,可选sourceNamespaceId表示源 namespace。 |
| HTTP Console API | Console 克隆中namespaceId表示源 namespace,targetNamespaceId表示目标 namespace;缺省namespaceId时源 namespace 默认等于目标 namespace。 |
| gRPC API | 查询、兼容发布、兼容删除、监听、模糊订阅和推送消息必须保持同一套 Config 身份和 md5 语义。 |
| Client SDK | 应用应优先使用运行时查询和监听 API;大范围管理 API 属于 Maintainer SDK。 |
6. 监听与订阅:精确监听、变更推送与模糊订阅
Config 监听与订阅规范定义了三类订阅语义。
6.1 精确监听
精确监听面向一个具体 Config 资源(namespaceId -> groupName -> dataId)。客户端为每个监听配置发送当前 md5,服务端维护:
- group key 到 connection id 的映射;
- connection id 到 group key 和 md5 的映射;
- 该连接是否需要 namespace 兼容转换。
注册监听时服务端比较客户端 md5 与服务端状态,如果客户端不是最新状态,响应中会包含发生变化的配置身份,客户端随后查询内容。
6.2 变更推送规则
发布、删除、元数据更新或灰度状态变化成功后,Config 领域发布本地变更事件。gRPC notifier 根据变化的 group key 找到监听连接,推送ConfigChangeNotifyRequest。推送规则:
- 推送携带变化的 Config身份,不携带权威配置内容;
- 客户端收到变更通知后必须查询Config;
- 推送使用重试、任务执行和 Control 点;
- 推送重试超过配置次数时,服务端可以注销失效连接;
- 断开的客户端会丢失内存中的监听状态,重连后必须重新注册。
变更事件的跨节点刷新可见性由 AP 一致性规范定义,推送重试与异步 notifier 执行遵循 任务执行规范。
6.3 模糊订阅
模糊订阅监听的是“模式”而不是单个精确 Config,模式生成格式为:
namespaceId >> groupPattern >> dataIdPattern模式使用*匹配:
| 模式形式 | 含义 |
|---|---|
* | 匹配该段所有值。 |
prefix* | 前缀匹配。 |
*suffix | 后缀匹配。 |
*text* | 包含匹配。 |
literal | 精确匹配。 |
服务端维护每个模式命中的 group key 集合:初始化时对比命中集合与客户端上报的集合,按批次推送ADD_CONFIG或DELETE_CONFIG状态;初始化后,Config 变化会更新命中集合并向匹配客户端推送变化事件。
6.4 模糊订阅限制(关键配置参数)
| 配置项 | 含义 | 默认值 |
|---|---|---|
nacos.config.fuzzy.watch.max.pattern.count | 限制跟踪模式数量 | 20 |
nacos.config.fuzzy.watch.max.pattern.match.config.count | 限制每个模式命中的配置数 | 500 |
nacos.config.push.batchSize | 控制初始化 diff 批大小 | 20 |
当某个模式达到命中配置上限时,服务端可以抑制后续新增命中项,并在命中集合不完整时保护删除通知。
监听诊断(Admin listener 和 metric API 可按配置身份、客户端 IP 和集群节点查询监听状态)属于管理诊断能力,不应通过运行时 Client SDK 暴露;服务端监听状态的实际维护逻辑可参考 RemoteConfigListenerStateServiceImpl.java。
7. 灰度发布:一个正式配置 + 多个灰度版本
Config 灰度发布规范定义了灰度模型与查询优先级。
7.1 模型
一个 Config 资源可以拥有:
- 一个正式配置;
- 零个或多个灰度配置版本。
灰度版本是同一 Config 身份下的从属发布状态:
namespaceId -> groupName -> dataId -> grayNamegrayName不是新的顶层 Config 资源。正式配置和灰度版本共享同一个namespaceId、groupName、dataId,但可以拥有不同的内容、md5、encrypted data key、最后修改时间和灰度规则。
7.2 灰度规则
| 字段 | 含义 |
|---|---|
type | 规则类型,例如beta或tag。 |
version | 规则解析版本。 |
expr | 原始规则表达式。 |
priority | 优先级,值越大越先匹配。 |
规则实现通过 Java SPI 加载GrayRule,规则必须可解析、有效并能匹配请求标签。内置规则:
| 规则 | grayName | 匹配标签 | 优先级 |
|---|---|---|---|
| Beta | beta | ClientIp在逗号分隔的 beta IP 列表中 | Integer.MAX_VALUE |
| Tag | tag_{tag} | Vipserver-Tag等于请求 tag 值 | Integer.MAX_VALUE - 1 |
存在多个灰度版本时,先按优先级降序匹配,优先级相同再按grayName排序。
7.3 发布、删除与查询
- 携带
betaIps的发布写入 beta 灰度版本;携带tag的发布写入 tag 灰度版本;没有灰度选择字段的发布写入正式配置。 - 灰度发布必须校验规则类型、版本、表达式和优先级;执行最大灰度版本数限制,默认通过
nacos.config.gray.version.max.count配置为10;持久化灰度内容和规则元数据;发布携带对应grayName的 Config 变更事件;记录灰度专用事件类型的持久化 trace。 - 删除灰度版本只移除该版本,不删除正式配置。
运行时查询先匹配灰度规则再回退正式配置:从客户端 IP、显式 tag 和连接标签构建请求标签 -> 遍历已排序灰度版本 -> 返回第一个命中的灰度版本 -> 显式 tag 未命中时返回 tag-specific not-found -> 否则返回正式配置。Admin beta 查询在 beta 版本存在时返回 beta 版本;Admin 正式查询不应静默返回灰度内容。
7.4 兼容与清理
当前领域模型是config_info_gray表加GrayRule;beta 和 tag 灰度版本同样通过config_info_gray中对应的grayName和序列化规则元数据表示。从 Nacos 3.3 版本线开始,运行时不再支持从 legacyconfig_info_beta、config_info_tag旧表向config_info_gray的兼容迁移;从 3.0 之前版本升级且使用过 beta 灰度发布的部署,必须在升级前完成相关数据迁移。
8. 持久化、Dump 与历史
Config 持久化、Dump 与历史规范定义了可靠状态与服务端缓存的分层。
8.1 持久化记录族
Config 领域通过 repository service 存储可靠状态:
| 记录族 | 目的 |
|---|---|
config_info | 正式 Config 内容、md5、类型、元数据、来源信息、namespace、group 和 encrypted data key。 |
config_info_gray | 灰度 Config 内容、md5、灰度名称、序列化灰度规则、namespace、group 和 encrypted data key。 |
his_config_info | 正式和灰度发布或删除操作的历史变更记录。 |
tenant_capacity/group_capacity | namespace、group 和 cluster 范围的容量限制和用量计数。 |
Repository 接口定义 Config 语义;具体 SQL 和数据库方言属于实现细节,由 数据源方言插件规范覆盖。
8.2 本地 Dump 缓存与变更 Dump 流程
每个服务端节点维护本地服务状态:以内部 group key 为键的 JVM 缓存(包含 md5、时间戳、encrypted data key、内容类型和灰度规则状态),以及保存正式和灰度配置内容的本地 dump 文件。源码中本地 dump 的目录前缀为config-data(Constants.java#L42 的BASE_DIR),服务端备份目录则位于~/nacos/bak_data。
启动阶段必须将持久化的正式和灰度配置 dump 到本地服务状态;运行时查询读取缓存和本地 dump 文件,不做大范围数据库查询。写入成功后,Config 发布变更事件,dump service 将事件转化为 dump 任务,任务从持久化层重新加载受影响的记录并更新本地缓存和 dump 文件。
Dump 的语义细节:
- Dump 必须忽略过期时间戳,保留更新的本地状态;
- md5 未变化但时间戳更新时,只更新时间戳状态而不重写内容;
- 内容变化时,同时更新本地文件内容和 JVM md5 状态。
8.3 嵌入式与外部存储
- 嵌入式存储必须等到 CP 协议已有可读数据后,才完成启动 dump;
- 外部存储直接从配置的数据源初始化 dump;
- 历史清理和管理类存储操作必须只在存储模式策略选中的节点上执行。
8.4 历史、恢复与运维
历史记录必须保留足够信息以便检查和恢复配置变化:身份三元组、内容和 md5、来源用户和 IP、操作类型(发布/删除)、发布类型(正式/灰度)、适用时的grayName和扩展信息、创建和修改时间。历史列表和详情 API 属于管理 API,分页大小必须有边界;历史清理使用配置的保留窗口,默认30天。
Admin 本地缓存操作可以触发从持久化层到本地缓存的全量 dump,该操作是管理修复机制,不应作为正常发布链路使用。当本地磁盘已满或无法安全保存 dump 内容时,服务端必须将其视为致命条件,因为运行时查询正确性依赖本地服务状态。
9. 一致性、Dump 顺序与集群可见性
Config 一致性、Dump 与可见性规范细化了写入如何对本地读取和 listener 可见。
9.1 权威状态
Config 资源的权威状态是配置的持久化层:
- 外部存储模式使用配置的外部数据库;
- 嵌入式存储模式使用 Config model Raft group 的 CP 路径;
- 本地磁盘 dump 是服务缓存,不是权威存储;过期或缺失的本地 dump 必须从持久化层修复。
9.2 写入路径
Config publish 或 delete 必须依次执行:
- 写入前校验 identity、参数、容量和鉴权;
- 通过 repository layer 持久化正式或灰度状态;
- 按 Config 操作规则记录历史和 trace 事实;
- 当写入需要刷新服务缓存并通知 listener 时,发布
ConfigDataChangeEvent或等价集群通知。
CAS 写入只有在持久化层确认 expected MD5 时才成功;CAS 失败不得发布变更事件。
9.3 两种存储模式下的可见性
外部存储:所有节点共享外部数据库。写入成功后,写入节点发布本地ConfigDataChangeEvent,并向其他集群节点发送ConfigChangeClusterSyncRequest。每个收到事件的节点为受影响的 config key 创建 dump task,运行时查询视图在该节点完成从持久化层到本地 cache 的 dump 后更新。该传播是基于 cluster request path 的 AP 风格通知:节点可能在收到通知、重试通知,或被周期性 full dump/change dump worker 修复前短暂落后。
嵌入式存储:持久顺序来自 Config model CP group。服务端必须等待 CP metadata 表明 leader 可用后,startup dump 才能安全读取数据;写入 commit 后必须通过 dump 刷新本地服务 cache,该节点的运行时 query 和 listener 视图才被视为已更新;变更通知不得绕过 CP commit 结果。leader-owned maintenance task(例如历史清理)只能由 leader 执行。
9.4 Dump 顺序与灰度可见性
Dump ordering 按 Config identity 生效:正式配置用dataId、groupName、namespaceId,灰度配置还包含grayName;同一 task key 上后来的 dump task 可以替换或合并更早的 pending work;dump task 必须读取该 identity 的最新持久化状态。Listener 和 fuzzy watch 通知必须从本地变更可见性发出,而不是从未提交的写入意图发出。
灰度配置从属于正式 Config identity,灰度 publish/delete 必须刷新对应grayName的灰度服务 cache。从 3.3 版本线开始,一致性和 dump 路径不再把 legacy beta/tag 存储行转换为grayName,也不再同步空 tenant 与public之间的默认 namespace 重复记录。
9.5 失败与恢复
- 本地磁盘无法安全保存 dump 内容时视为致命问题;
- 集群通知失败时使用有界或退避调度重试,并由周期性 dump path 修复;
- 节点重启时,startup dump 必须从持久化层重建本地服务 cache,节点才被视为具备 Config 查询正确性;
- 客户端错过 push 时,通过 listener resync 和 query 恢复(遵循 运行时推送与重连规范)。
10. 容量与运维
Config 容量与运维规范定义了容量保护和运维 API。
10.1 容量范围与限制项
容量用于保护 cluster、namespace 和 group 资源:
| 范围 | 含义 |
|---|---|
| Cluster | 集群内正式 Config 总数。 |
| Namespace | 单个 namespace 下的正式 Config 数量。 |
| Group | 不使用 namespace 维度容量时,单个 group 下的正式 Config 数量。 |
容量只适用于正式 Config 记录——灰度版本是已有 Config 的发布状态,不作为独立正式配置计数。
| 字段 | 含义 |
|---|---|
quota | 该范围内 Config 记录数量上限;0表示使用默认值。 |
usage | 当前统计的 Config 记录数量。 |
maxSize | 单个 Config 内容大小上限(字节);0表示使用默认值。 |
服务端配置默认值:
| 配置项 | 默认值 |
|---|---|
defaultClusterQuota | 100000 |
defaultGroupQuota | 200 |
defaultTenantQuota | 200 |
defaultMaxSize | 100 * 1024字节 |
correctUsageDelay | 600秒 |
initialExpansionPercent | 100 |
执行规则上有两个开关:isManageCapacity启用发布和删除周围的用量统计;isCapacityLimitCheck启用配额和大小拒绝。启用限制检查时,插入新正式配置必须:检查并递增 cluster 用量 -> 检查内容大小 -> namespace 非空时检查并递增 namespace 用量,否则检查并递增 group 用量 -> 发布失败则回滚用量。更新已有配置只检查内容大小不增加用量;删除已有配置递减用量并在删除失败时回滚。并发删除和异步写入可能使计数短暂不准确,系统会周期性修正用量。
规范同时明确:maxAggrCount、maxAggrSize等聚合配置字段属于历史冗余设计,已标记为待移除对象,新的规范、API、SDK 和文档不应基于聚合配置定义正式行为。
10.2 容量 API 与运维 API
Capacity Admin API 可查询或更新 namespace 或 group 的容量,必须至少提供namespaceId或groupName之一;容量记录不存在时,服务端先初始化再返回应用默认值后的有效容量。容量 API 是管理 API,不应通过运行时 Client SDK 暴露。
Config 运维 API 是管理修复或诊断接口(对应源码中的 ConfigOpsControllerV3.java):
| 操作 | 规则 |
|---|---|
| 本地缓存 dump | 从持久化层全量刷新本地缓存。 |
| 日志级别更新 | 修改 Config 模块日志级别。 |
| Derby 查询 | 仅当嵌入式存储启用且nacos.config.derby.ops.enabled=true时,允许有边界的SELECT语句。 |
| Derby 导入 | 仅当嵌入式存储启用且 Derby ops 已启用时,导入 Derby 数据。 |
| 监听诊断 | 按 IP 或 Config 身份查询监听状态。 |
| 指标 | 在本节点或跨集群成员查询客户端缓存和快照指标,遵循 可观测钩子规范。 |
Derby ops 属于 maintainer-only 行为,必须要求 Admin 权限,并默认保持关闭。
11. 基础能力对齐与延伸阅读
Config 的共享基础设施边界由以下基础规范统一约束,阅读时可以按需深入:
- 共享 datasource、嵌入式/外部存储、repository、dump 和 cache 边界:持久化与 Dump 规范;
- Config 特有的写入可见性、dump 恢复和集群变更传播:Config 一致性、Dump 与可见性规范;
- 共享任务执行和本地事件边界:任务执行规范、事件分发与 NotifyCenter 规范;
- 可观测边界:可观测钩子规范。
其中一条容易被忽略但非常重要的约束:Config trace 与审计字段应遵循可观测规范中的共享字段指引,并且不得包含完整 Config content——这保证审计日志不会成为配置明文内容的泄露渠道。
Config 领域的完整规范族入口见 Config 规范目录,本文各章节对应的子规范(资源、发布查询、监听订阅、灰度、持久化历史、一致性可见性、容量运维)均在该目录下,可作为进一步查阅的索引。
【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考