Nacos 资源模型(Resource Model)规范深度解析:从命名空间到 AI 资源的统一标识体系
【免费下载链接】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/en/design/resource-model-spec.md 编写,并结合仓库源码与相关子规范进行深度佐证。Nacos 是一个面向云原生与 AI 原生应用的动态服务发现、配置管理与服务治理平台。本文聚焦其统一资源模型(
NamespaceId -> Group/resourceType -> resourceName),解析微服务资源与 AI 资源两大分支的标识设计、治理属性、可见性/生命周期规则、API 表达规范,以及新增资源类型的落地清单,帮助开发者、平台工程师与 AI 资产管理者在接入 Nacos 时准确理解"一个资源到底由什么唯一确定"这一核心问题,并据此规范地设计 API、SDK 与数据模型。
1. 为什么需要一份统一的资源模型规范
Nacos 的能力面横跨配置管理(Config)、服务发现(Naming)、AI 资产注册(AI Registry,如 MCP Server、Agent、Prompt、Skill、AgentSpec)以及服务器控制面(Core)。这些能力分别通过 HTTP API、gRPC API、客户端 SDK、维护者 SDK(Maintainer SDK)与控制台暴露。如果没有一份统一的语义模型,HTTP 路径参数、gRPC 请求对象、SDK 方法签名、持久化表结构与控制台表单很容易各自为政,最终导致同一份资源在不同接口面上"长得不一样"。
resource-model-spec.md 正是为了解决这个问题而存在:它是 Nacos 共享资源模型的语义源头(semantic source),同时约束了 HTTP API、gRPC API、SDK、控制台工作流、持久化模型与文档。它细化了 Nacos Design Spec 中定义的顶层领域结构,是阅读其他所有领域规范(Config、Naming、AI 各资源规范)之前必须先理解的基础。
从 nacos-design-spec.md 第 4 节可以看到,所有 Nacos 领域都被要求围绕统一的资源层级来组织:
NamespaceId -> Group/resourceType -> resourceName领域规范可以进一步定义版本、标签、状态、可见性等治理属性,但不得破坏这个顶层三层结构。这意味着"一个 Nacos 资源由什么唯一确定"在全局只有一个答案,其余字段都只是治理属性。
2. 顶层资源层级:三层标识结构
规范定义 Nacos 顶层资源标识由三层组成:
NamespaceId -> Group/resourceType -> resourceName各层的含义与作用域如下表所示:
| 层级 | 含义 | 作用域 |
|---|---|---|
NamespaceId | 面向租户、团队、环境或管理域的隔离边界 | 所有租户级资源(tenant-scoped resources) |
Group/resourceType | 第二级分类器。微服务资源使用概念性的Group;AI 资源使用resourceType | 领域相关(domain-specific) |
resourceName | 在父级作用域内唯一标识某个具体资源的稳定名称 | 所有具名资源 |
规范特别强调:Group与resourceType绝不能混为同一个字段。
Group是微服务资源的业务分组,主要服务于配置与命名资源;resourceType是类型分类器,服务于共享同一治理模型的资源,主要用于 AI Registry 资源。
由此,Nacos 存在两条主资源模型分支:
- 微服务资源模型:
NamespaceId -> Group -> resourceName; - AI 资源模型:
NamespaceId -> resourceType -> resourceName。
同时,规范明确:版本(version)、标签(labels)、状态(status)、可见性(visibility)、所有者(owner)与元数据(metadata)都是资源的治理属性,除非领域规范明确说明,否则它们不属于顶层三层标识的一部分。这一点是理解 Nacos 资源"身份"与"状态"分离的关键——改变元数据不会改变资源的身份,而改变 resourceName 则是删除重建或克隆操作。
3. 第一层:NamespaceId 命名空间
NamespaceId是 Nacos 主要的隔离边界,用于隔离租户、团队、环境或其他管理范围。规范给出的规范名称与兼容名称如下:
| 概念 | 规范名称 | 兼容名称 |
|---|---|---|
| 命名空间 ID | namespaceId或namespace | tenant、tenantId |
| 显示名称 | namespaceShowName | tenantName |
| 描述 | namespaceDesc | tenantDesc |
默认命名空间 ID 为public。历史代码中可能使用tenant或tenantId,但新的公共 API 与规范应使用namespaceId,除非既有兼容性契约要求其他名称。
这一点在源码中有直接印证。在 api/src/main/java/com/alibaba/nacos/api/common/Constants.java 中可以看到DEFAULT_NAMESPACE_ID = "public"、TENANT = "tenant"、NAMESPACE_ID = "namespaceId"等常量同时存在,正是"兼容名称与规范名称并存"的代码级证据。而在 api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java 中,namespaceId为空时会回退为Constants.DEFAULT_NAMESPACE_ID。
跨命名空间的操作属于管理操作,必须走 Admin API、Console API 或 Maintainer SDK 接口面,普通运行时客户端 SDK 不应拥有跨命名空间能力。
4. 第二层:Group 与 resourceType
第二层在命名空间内进一步分类资源,但语义因领域而异。
4.1 Group:微服务资源的业务分组
Group是微服务资源的业务分组,是配置与命名资源标识的一部分,在受支持的接口未指定时默认为DEFAULT_GROUP。它适合在同一资源族内部进行业务隔离,例如按应用、业务线、环境本地分组或用户自定义分组。
Group不表达资源类型——因此一个配置(Config)和一个服务(Service)可以存在于同一个 Group 之下。当 Group 层在新规范、HTTP API、SDK 或面向用户的文档中以具体公共字段表达时,字段名应为groupName;而较短的group属于概念术语、内部模型字段或兼容字段。
源码佐证:在 Constants.java 中DEFAULT_GROUP = "DEFAULT_GROUP";在 Service.java 中服务模型的公共字段即为groupName。内部合并表示group@@serviceName由 NamingUtils.java 的getGroupedName(serviceName, groupName)生成(使用Constants.SERVICE_INFO_SPLITER,即@@),而公共 API 与规范应优先使用分离的groupName与serviceName字段。
4.2 resourceType:AI 资源的类型分类器
resourceType是类型分类器,适合包含多种资源类型的共享治理模型,例如 AI Registry 的资源类型:mcp、agent、prompt、skill与agentspec。
resourceType不是业务分组。AI 资源不应引入 Group 身份字段,除非领域规范明确定义了附加语义。这一设计在 AI Resource Model Spec 中有更细化的体现:AiResource元数据行的type字段即取值为mcp、agent、prompt、skill、agentspec之一。
5. 第三层:resourceName 具体资源名
resourceName是资源在NamespaceId + Group/resourceType下的稳定名称。不同领域暴露领域化的具体名称:
| 领域 | 具体 resourceName |
|---|---|
| 配置 Config | dataId |
| 命名服务 Naming service | serviceName |
| MCP Server | name或mcpName |
| Agent | agentName |
| Prompt | promptKey |
| Skill | name |
| AgentSpec | name |
resourceName是身份字段,不应作为普通元数据被修改。更新 resourceName 本质上是一次"删除并重建"或"克隆"操作,除非领域规范定义了迁移操作。
源码层面,AiService.java 中的getPrompt(promptKey)、getPromptByVersion(promptKey, version)、getPromptByLabel(promptKey, label)等 API 均以promptKey作为 Prompt 的 resourceName;A2aService.java 中的getAgentCard(agentName, ...)则以agentName标识 Agent。这正是"不同领域暴露领域化名称"在公开 SDK 接口上的直接体现。
6. 微服务资源模型
微服务资源模型使用:
NamespaceId -> Group -> resourceName它覆盖传统的 Nacos 配置与命名能力。
6.1 配置资源(Config Resource)
Config 资源的标识为:
namespaceId -> groupName -> dataIdConfig 资源拥有:
- 内容与 md5(content 和 md5);
- 配置类型(config type);
- 描述、标签与应用名元数据(description、tags、app name metadata);
- 发布、CAS 发布、删除与查询语义;
- 监听与模糊监听(fuzzy-watch)语义;
- 灰度/测试(gray/beta)发布状态;
- 历史、回滚、转储与容灾数据(history、rollback、dump、failover data)。
dataId是 Config 的 resourceName。appName、type、desc、configTags等元数据不改变身份。详细规则见 Config Resource Spec。
值得特别注意的是 Prompt 与配置存储之间的兼容映射:Prompt 以固定 Groupnacos-ai-prompt、dataId{promptKey}.json存储在配置中。这一映射只是兼容性存储形态,绝不能在新型规范中把 Prompt 当作普通 Config 资源对待。源码印证:在 api/src/main/java/com/alibaba/nacos/api/ai/model/prompt/Prompt.java 的类注释中明确写着 "Prompt is stored as a Nacos configuration with fixed groupnacos-ai-promptand dataId{promptKey}.json",并且 Prompt 模型包含promptKey、version(格式如 "1.0.0")、template、md5、variables等字段——其语义身份是namespaceId -> prompt -> promptKey,而非普通配置。
6.2 命名服务资源(Naming Service Resource)
命名服务资源的标识为:
namespaceId -> groupName -> serviceName命名服务资源拥有:
- 服务元数据与内部过滤信息;
- 临时服务(ephemeral-service)或持久服务(persistent-service)语义;
- 集群与健康检查配置;
- 订阅者、发布者与客户端连接视图;
- 服务与实例变更事件。
内部合并名称(internal grouped names)可以使用group@@serviceName,但公共 API 与规范应优先使用分离的groupName与serviceName字段。详细规则见 Naming Resource Spec。
6.3 集群与实例(Cluster And Instance)
Cluster 与 Instance 是服务的从属资源,不改变顶层三层模型:
namespaceId -> groupName -> serviceName -> clusterName -> instance实例身份通常由服务作用域、clusterName、ip与port共同决定;instanceId可以是生成的或由外部提供的运行时标识符。实例包含ip、port、clusterName、weight、healthy、enabled、ephemeral、metadata与可选的instanceId。实例绝不能脱离其服务作用域被单独解释。
在 api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java 中,Instance类字段与规范完全对应:instanceId、ip、port、weight(默认1.0D)、healthy(默认true)、enabled(默认true)、ephemeral(默认true)、clusterName、serviceName、metadata(Map<String, String>)。而 NamingUtils.checkServiceNameFormat 则校验合并名称必须形如groupName@@serviceName,进一步印证了内部合并表示与公共分离字段的并存关系。
临时服务与持久服务的语义会影响生命周期与一致性行为,并且必须在 HTTP、gRPC、SDK 与存储模型之间保持一致。
7. AI 资源模型
AI 资源模型使用:
NamespaceId -> resourceType -> resourceName它覆盖 AI Registry 资源,包括 MCP Server、Agent、Prompt、Skill 与 AgentSpec。共享 AI 模型由 AI Registry Spec 与 AI Resource Model Spec 定义。
7.1 共享治理属性
AI 资源共享以下治理属性:
| 属性 | 含义 |
|---|---|
version | 资源版本,构成NamespaceId + resourceType + resourceName + version |
labels | 标签到版本的映射,如latest、stable |
status | 资源或版本的生命周期状态 |
visibility | 可见性范围,如PUBLIC或PRIVATE |
owner | 所有者身份 |
bizTags/metadata/ext | 不参与身份的业务或扩展元数据 |
pipeline | 发布审核或自动化状态 |
AI 资源元数据身份是namespaceId + resourceType + resourceName;AI 资源版本身份是namespaceId + resourceType + resourceName + version。
已发布的 AI 版本应视为不可变(immutable),除非领域规范明确定义了安全的变更方式。变更的正确姿势是:创建新的草稿版本(draft)→ 按需通过审核(review)→ 发布或重新打标签(relabel)。这一"版本中心"设计的原因在 AI Resource Model Spec 第 7 节有说明:AI 资产的变化频率往往高于应用配置或服务发现数据。
该规范还给出了两层数据模型:AiResource元数据行包含namespaceId、type、name、desc、status(enable/disable)、owner、scope、bizTags、ext、from、versionInfo、metaVersion(乐观锁,用于元数据 CAS 更新)与downloadCount;AiResourceVersion版本行则包含version、author、desc、status、storage(指向由 AI 存储插件管理的内容存储)、publishPipelineInfo与downloadCount。versionInfoJSON 中最多只应存在一个editingVersion和一个reviewingVersion,且标签不得指向草稿或审核中的版本。
7.2 MCP Server
MCP Server 的规范资源标识为:
namespaceId -> mcp -> mcpNameMCP Server 资源描述具备 MCP 能力的服务。它们可以来源于:新建的 MCP Server、导入的外部 MCP Server,或将既有 HTTP/RPC 服务适配而成的 MCP 服务。MCP Server 可以携带注册中心的id,但mcpName仍然是面向用户的 resourceName。MCP 特有元数据包括协议、前置协议(front protocol)、仓库、包、图标、网站 URL、本地或远端服务配置、端点规范、工具规范、状态与已发现的能力(discovered capabilities)。
7.3 Agent
Agent 的规范资源标识为:
namespaceId -> agent -> agentNameAgent 拥有目录(directory)与治理元数据。每个 Agent 版本拥有一组有序的、协议无关的调用接口(call interfaces)。A2A 只是其中一种协议绑定(其原生描述符是 AgentCard),并不是第二个顶层 AI 资源身份。运行时端点具有客户端拥有的生命周期,并被投射(projected)到 Agent 发现中,但不会成为版本内容。
完整模型由 Agent Management Spec 定义;远端消费者发现遵循 RAD Protocol Spec;遗留 AgentCard API 则是 A2A Agent Spec 定义的兼容门面。
7.4 Prompt
Prompt 的规范资源标识为:
namespaceId -> prompt -> promptKey版本标识为:
namespaceId -> prompt -> promptKey -> versionPrompt 包含模板内容、变量、md5 与版本元数据。运行时的 Prompt 查询应按"显式版本 → 标签 →latest"的顺序解析,具体以相关 API 或 SDK 契约为准。这一解析顺序与 AiService.java 中getPrompt/getPromptByVersion/getPromptByLabel的 API 划分完全吻合。
7.5 Skill
Skill 的规范资源标识为:
namespaceId -> skill -> skillNameSkill 代表可复用的 AI Agent 能力。Skill 包含元数据、指令内容、可选资源、版本、标签、可见性与发布流水线元数据。Skill 版本依次经历draft(草稿)、reviewing(审核中)、reviewed(已审核)、online(在线)、offline(下线)状态。除非管理 API 明确请求其他状态,否则只有 online 版本应返回给运行时客户端。
7.6 AgentSpec
AgentSpec 的规范资源标识为:
namespaceId -> agentspec -> agentSpecNameAgentSpec 通过引用 Prompt、Skill、MCP Server、Agent 或其他必需资源来装配 Agent 配置。AgentSpec 应通过稳定的身份与版本/标签引用其他资源,而不是通过存储实现细节(如存储表或内部 ID)来引用。
8. 可见性与所有权
支持可见性的资源必须暴露:
namespaceId;resourceType;- 稳定的 resourceName;
scope(目前为PUBLIC或PRIVATE);- 所有者身份(owner identity)。
可见性影响发现、详情查看、下载与写操作。规范强调:可见性是对授权的补充,绝不能替代权限检查。权限语义由 Auth And Permission Spec 定义。从仓库结构看,可见性插件契约由 Visibility Plugin Spec 定义,其实现位于plugin/visibility模块,并在 AI Resource Model Spec 第 6 节中细化了读写规则(例如:读操作在资源存在但调用者不可见时应返回 not found;查询操作应尽量使用可见性查询建议(visibility query advice)而非对大数据集做后置过滤)。
9. 状态与生命周期
状态值因领域而异,但必须显式且文档化:
- 配置资源:使用发布、灰度/测试、历史与监听状态;
- 命名资源:使用服务类型、实例、健康、启用与生命周期状态;
- AI 资源:使用元数据状态、版本状态、标签、流水线状态与可见性状态;
- 核心资源:使用服务器、成员、就绪(readiness)、存活(liveness)、插件与连接状态。
运行时 API 应只返回面向运行时消费的状态;管理 API 在授权后可以返回草稿、审核、下线、内部或运维状态。这一"面向运行时 vs 面向管理"的双轨状态视图,与前面 Skill 版本"只有 online 版本返回给运行时客户端"的规则一脉相承。
10. API 表达规则:所有接口族必须保持同一资源身份
所有 API 族必须保持相同的资源身份:
- HTTP:路径与参数名称应使用本规范的规范资源术语;
- gRPC:请求对象应携带相同的身份字段,即使传输载荷是 JSON 编码;
- 客户端 SDK:应暴露运行时安全的资源操作;
- Maintainer SDK:应暴露广泛的管理资源操作;
- Console API:可以为 UI 调整数据形态,但不得重新定义资源身份。
如果历史 API 使用了兼容名称,实现应在内部将其映射为规范资源术语,并文档化别名。从 v3-api-surface.md 可以看到这一原则的实际落地:/v3/client/ai/resources(跨资源协议无关搜索)、/v3/client/ai/prompt、/v3/client/ai/skills、/v3/client/ai/agentspecs、/v3/client/ai/mcp等运行时 AI 接口与/v3/admin/ai/*管理接口并行存在,前者只暴露运行时安全操作,后者承载管理语义——这与"运行时 API 与管理 API 分离""Console API 不得重定义资源身份"的规则一致。
11. 新增资源类型检查清单
任何新资源类型都必须明确回答以下问题:
- 所属领域与模块(owning domain and module);
- 规范身份字段(canonical identity fields);
- 第二层是
Group还是resourceType; - resourceName 的具体业务名称;
- 版本、标签、状态与可见性行为;
- 运行时 API、管理 API 与 SDK 暴露方式;
- 授权与审计要求;
- 持久化与缓存预期;
- 兼容别名(如有)。
这份清单同样与 nacos-design-spec.md 第 8 节"新特性设计规则"相呼应——如果一个新特性无法回答"领域归属、资源类型与身份、面向运行时还是管理、API 受众、命名空间/分组/版本/标签/状态/可见性行为、认证授权与审计、兼容性与废弃影响、测试与验证规则"这些问题,它就没有资格成为稳定的 Nacos 契约。
12. 实战指南:如何在你的项目中应用这套模型
基于上述规范,在实际接入 Nacos 时建议遵循以下要点:
- 先定身份,再谈功能:任何新接入的资源,先明确其三层身份是
NamespaceId -> Group -> resourceName还是NamespaceId -> resourceType -> resourceName。不要为了复用现有表结构而强行把一个 AI 资源伪装成普通配置资源(Prompt 的nacos-ai-prompt固定分组映射只是兼容存储形态)。 - 公共接口优先用规范名称:新 HTTP API、gRPC 请求对象、SDK 方法与文档一律使用
namespaceId、groupName、dataId、serviceName、mcpName、agentName、promptKey等规范术语;tenant、group等仅在兼容层使用并在内部映射。 - 身份字段不可当作元数据修改:修改 resourceName(如 dataId、serviceName、promptKey)等于删除重建或克隆;普通元数据变更(描述、标签、权重等)不影响身份。
- AI 资产遵循"版本中心"工作流:发布版本视为不可变,变更走"新建草稿 → 审核 → 发布/重新打标签",运行时查询按"显式版本 → 标签 → latest"解析。
- 区分运行时面与管理面:运行时 API 只暴露运行时可安全消费的状态(如仅 online 的 Skill 版本);草稿、审核、下线等状态留给管理 API,并且必须经过授权。
- 可见性不替代权限:
PUBLIC/PRIVATE范围只决定发现与读取范围,权限校验必须依赖 Auth And Permission Spec 定义的安全体系。 - 新增资源类型先过检查清单:动手实现前,先用第 11 节清单逐项核对,确保新资源能融入统一的身份、API、授权与持久化框架。
相关文档导航
- 顶层设计:Nacos Design Spec
- 配置资源:Config Resource Spec 与 Config Spec
- 命名资源:Naming Resource Spec 与 Naming Spec
- AI 资源:AI Registry Spec、AI Resource Model Spec、MCP Server Spec、Agent Management Spec、Prompt Spec、Skill Spec、AgentSpec Spec
- 接口规则:HTTP API Spec、gRPC API Spec、SDK Spec
- 安全与可见性:Auth And Permission Spec、Visibility Plugin Spec
- 关键源码:公共常量 Constants.java、命名工具 NamingUtils.java、服务模型 Service.java、实例模型 Instance.java、AI 接口 AiService.java、Prompt 模型 Prompt.java
【免费下载链接】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),仅供参考