☰
Nacos Naming 顶层规范解读:服务发现领域的定位、资源模型与一致性架构
2026/10/5 9:47:18 网站建设 项目流程

Nacos Naming 顶层规范解读:服务发现领域的定位、资源模型与一致性架构

【免费下载链接】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 Naming 是 Nacos 中负责服务发现的一级领域,管理服务、集群、实例及其元数据、健康状态与订阅关系。本文基于 Naming 规范 展开,系统讲解其领域定位、资源身份层次、临时/持久两种服务类型的语义差异、六条设计原则、接口面划分与边界约束,并结合 naming 模块源码与各子规范说明底层实现脉络。读完本文,你将掌握 Nacos 服务发现领域的顶层设计骨架,以及各子规范(资源、发现订阅、健康保护、生命周期、一致性)之间的关联与定位。

1. Naming 领域的定位

Nacos Naming 是服务发现领域,它管理服务、集群、实例、服务元数据、实例元数据、健康状态、订阅者、发布者和客户端服务视图。Naming 是 Nacos 的一级领域,不是通用流量治理引擎、服务网格控制面、配置存储或 AI Registry 模型。

它可以提供内部过滤、客户端 selector、权重、健康保护和元数据能力,但这些能力必须限定在服务发现语义内。这一边界在 第 7 节 有更详细的约束。

Naming 规范建立在两个基础规范之上:

  • Nacos 设计规范
  • 资源模型规范

按 README 的说明,这些规范来自当前naming、api、client、core、consistency和maintainer-client的实现,属于"以当前代码为来源"的规范。

2. 资源身份:namespaceId -> groupName -> serviceName

Naming 使用微服务资源层次标识资源:

namespaceId -> groupName -> serviceName

Cluster 和 Instance 是从属资源:

namespaceId -> groupName -> serviceName -> clusterName -> instance

2.1 Service 身份字段

字段含义说明
namespaceId服务所属 namespace当接口支持默认值处理时,空值或缺省值会被处理为默认 namespace id
groupNamenamespace 内的业务分组新公开规范和 v3 接口使用groupName;兼容 key 中仍可能使用group@@serviceName
serviceName服务资源名serviceName是 Naming service 的resourceName

身份字段是稳定的。修改namespaceId、groupName或serviceName表示创建了新的 service 资源,而不是普通元数据更新。详细规则见 Naming 资源规范。

2.2 Instance 资源

Instance 从属于 service 和 cluster:

namespaceId -> groupName -> serviceName -> clusterName -> ip:port
字段含义
ip实例地址,必填
port实例端口,必填,范围0..65535
clusterName实例所属 cluster,默认为DEFAULT
weight实例流量权重,默认为1.0
healthy运行时健康状态,默认为true,可被心跳或主动健康检查改变
enabled实例是否可被运行时消费者发现,默认为true
ephemeral兼容和路由字段,必须与所属 service 类型匹配,默认true
metadata实例元数据 key-value map
instanceId可选的生成或用户指定运行时标识

公开身份应使用 service scope 加clusterName、ip和port。instanceId是运行时标识,不应在新 API 中替代规范化身份字段。

2.3 内部 Key

实现代码中会使用以下兼容 key:

  • grouped service name:group@@serviceName
  • service key:namespace@@group@@serviceName
  • service info key:group@@serviceName@@clusters
  • metadata id:由 instanceip、port和clusterName生成

这些 key 是实现和兼容 key。新 API 和 SDK 契约应优先使用显式namespaceId、groupName、serviceName、clusterName、ip和port字段。

3. 服务类型:临时服务与持久服务

每个 Naming service 都属于以下一种服务类型:

服务类型含义主要状态路径
临时服务非持久化运行时服务。实例由存活的 client 持有,并会随心跳或连接过期而消失偏 AP 的临时 client state 和 Distro 同步
持久服务持久化服务。实例作为持久资源管理,并可以从服务端 snapshot 恢复偏 CP 的持久 client state 和元数据持久化

服务类型是 service 级语义属性。Instance 的ephemeral输入必须与所属 service 类型匹配。实现中可以在 instance 上保留ephemeral字段用于兼容和路由,但新行为不得把它当作可以在同一个 service 内混用类型的独立实例策略。

对应校验规则在 Naming 资源规范 中有明确表述:持久实例不得注册到临时服务,临时实例也不得注册到持久服务。

4. 规范层次:一张完整的 Naming 规范地图

Naming 顶层规范把全部能力拆解为两类子规范,形成清晰的层次结构。

4.1 通用规范

责任含义详细规范
资源模型定义 service、cluster、instance、client、publisher 和 subscriber 身份Naming 资源规范
发现与订阅定义查询、订阅、推送、模糊订阅、本地缓存和 failover 视图Naming 发现与订阅规范
健康检查与保护定义健康状态、主动健康检查、enabled 状态、权重、内部过滤和保护阈值Naming 健康检查与保护规范
元数据与 selector定义 service、cluster、instance 元数据、运行时与运维态元数据优先级、保留 key、内部过滤、遗留 API selector 和客户端 selector 行为Naming 元数据与 Selector 规范
运维定义 client 诊断、subscriber 诊断、指标、开关、日志级别和清理边界Naming 运维规范

4.2 按服务类型分化的规范

责任含义详细规范
实例生命周期定义通用生命周期,以及按服务类型区分的注册、心跳、注销、更新、批量注册和清理行为Naming 实例生命周期规范
一致性与客户端状态定义通用 client 身份,以及临时服务 AP 状态、持久服务 CP 状态、索引和 snapshotNaming 一致性与客户端状态规范
临时服务 Distro 一致性定义临时 ownership、Distro 同步、verify、anti-entropy、清理和 AP 可见性Naming 临时服务 Distro 一致性规范
持久服务 CP 一致性定义持久实例 CP 写入、metadata group、snapshot、恢复和可见性Naming 持久服务 CP 一致性规范

5. 六条设计原则

5.1 Service 是发现单元

Naming service 是可寻址的服务发现单元。Instance 必须在 service scope 和 cluster scope 下理解,脱离namespaceId、groupName和serviceName的 instance 不是完整的 Naming 资源。

5.2 运行面与管理面分离

运行时客户端注册或注销自己的实例、查询已知服务并订阅服务变化;而服务创建、服务删除、服务元数据、集群元数据、client 诊断、subscriber 诊断、指标、开关和日志级别操作属于管理能力,应通过 Admin API、Console API 或 Maintainer SDK 暴露。

HTTP Open API 面向无法使用 gRPC 的自定义客户端,提供指定服务的注册、心跳、注销和列表查询,不应扩展为大范围服务管理或推送订阅 API。

5.3 临时服务与持久服务是不同语义

临时服务是非持久化运行时服务,其实例绑定 client 存活状态,并使用偏 AP 的临时路径;持久服务是持久化服务,其实例使用偏 CP 的持久路径。API、SDK 和存储代码必须保留此区别,不能把ephemeral仅作为展示字段处理。

5.4 发现视图是过滤后的状态

Naming 发现结果不是原始存储 dump。查询和订阅结果可能经过 cluster、enabled 状态、健康状态、服务端内部过滤规则和保护阈值过滤。SDK selection 会在服务端提供的ServiceInfo视图之上继续做客户端 selector 和权重选择。

5.5 推送更新客户端视图

gRPC 订阅推送携带已订阅服务的最新ServiceInfo状态。客户端将推送状态保存到内存和磁盘缓存,比较实例 diff,通知 listener,并在重连、缓存缺失或轮询兜底时重新查询。HTTP Open API 不提供长轮询或推送订阅。

5.6 横切能力通过扩展接入

Naming 可以集成扩展机制,但 Naming 领域归属不转移:

关注点规则
鉴权Naming API 和 gRPC handler 使用 Naming 资源,并遵循鉴权与权限规范
可见性对 service、instance、subscriber 或 client 的范围查询,在启用可见性插件时应应用可见性规则
Control高频注册、注销、查询、订阅、推送和列表流程应暴露稳定的 Control 点,遵循 Control 插件规范
Trace 与指标Naming 生命周期事件应遵循 Trace 插件规范;共享指标和诊断遵循可观测钩子规范
健康检查扩展健康检查类型通过 health checker registry 加载,并必须保持 service/cluster/instance 资源模型不变
寻址客户端服务端寻址应遵循寻址插件规范

6. 接口面:六个入口的职责划分

接口面范围
HTTP Open API/v3/client/ns/instance面向自定义运行时客户端提供注册、心跳、注销和列表查询
HTTP Admin API/v3/admin/ns/*提供 service、instance、cluster、health、client 和运维管理
gRPC API提供运行时注册、批量注册、持久注册、查询、订阅、模糊订阅和服务端推送,参见 gRPC API 规范
Client SDK通过NamingService面向运行时应用提供注册、注销、查询、订阅、模糊订阅、本地缓存和 failover,参见 SDK 规范 和客户端运行时规范
Maintainer SDK通过 naming maintainer service 提供管理类接入
Console API面向 UI 的管理流程。Console API 可以调整展示形态,但不能重新定义 Naming 语义

以 Client SDK 为例,NamingService 接口提供了完整的运行时能力:getAllInstances返回当前视图,selectInstances按健康、enabled 状态和正权重过滤,selectOneHealthyInstance按权重选择一个实例,以及subscribe/unsubscribe接收NamingEvent或客户端 selector-based event,fuzzyWatchWithServiceKeys进行基于 pattern 的 service-key 订阅。SDK selection 只作用在客户端进程内,不应视为服务端流量策略。

7. 边界:明确什么不属于 Naming

  • Naming 不拥有配置内容或 Config listener 语义。
  • Naming 不拥有 AI 资源身份。AI 资源可以引用 Naming service 或 endpoint,但引用关系不应让 AI 资源变成普通 Naming service。
  • Naming metadata 是 key-value 服务发现元数据。只有 Naming 明确定义的保留元数据 key 才能改变核心行为。
  • Naming 健康检查用于判断发现可用性,不是通用应用观测或 SLA 系统。
  • 内部过滤和 SDK selector 是发现侧过滤与选择工具。遗留 API 定义的 service selector 是兼容字段,不应成为新流量策略语义的基础。

8. 源码中的实现锚点

顶层规范中的抽象概念在源码中都有对应的实现锚点,便于深入研读:

  • Distro 数据模型:临时服务的 Distro 同步使用 resource typeNacos:Naming:v2:ClientData,定义在 DistroClientDataProcessor,resource key 为 client id。Distro 不以 service 级记录作为权威来源,service view 由 client state 和索引派生。
  • 持久服务 CP group:持久实例发布状态使用Constants.NAMING_PERSISTENT_SERVICE_GROUP_V2(值为naming_persistent_service_v2),定义在 Constants,由 PersistentClientOperationServiceImpl 引用。
  • client 状态模型:gRPC 连接、HTTP connection-based client、IP-port client 的生命周期差异,见 Naming 一致性与客户端状态规范 与 Naming 临时服务 Distro 一致性规范。
  • 健康保护:protectThreshold用于防止发现结果收缩到过少健康实例,详细语义见 Naming 健康检查与保护规范。
  • 订阅与推送:gRPC 订阅记录 subscriber 并返回当前ServiceInfo视图,变更推送遵循事件分发与 NotifyCenter 规范。

9. 深入子规范:从顶层到实现细节

顶层规范只定义骨架,完整的可操作语义落在各子规范中。以下是对关键子规范的精读摘要,帮助读者按图索骥。

9.1 实例生命周期(注册 -> 心跳 -> 注销 -> 清理)

实例生命周期规范 定义了 service 和 instance 的完整生命周期:

  • Service 生命周期:Admin 创建 service 时必须选择临时或持久类型,后续注册必须匹配;只有无已注册实例时才允许删除 service;运行时实例注册可以隐式创建 service singleton。
  • 实例注册:必须校验字段和心跳元数据、填充 cluster 默认值、解析服务类型、确保ephemeral匹配、派生 client id、走对应操作路径,并通过 Naming 事件更新索引与 storage,最后发布 trace 事件。
  • 心跳:HTTP Open API 心跳复用POST /v3/client/ns/instance并设置heartBeat=true;gRPC 临时服务通过连接生命周期事件保活。心跳找不到 instance 时返回INSTANCE_NOT_FOUND,调用方应重新注册。
  • 注销:幂等 no-op 设计——注销不存在的实例或兼容 client 应视为成功;最后一个 publisher 消失时发出 delete-service 变更事件。
  • 更新:全量更新校验权重并替换运维态 metadata,局部更新只修改显式出现的字段;更新不改变 service 身份。
  • 批量操作:批量注册是临时服务 gRPC 能力,输入必须为合法临时实例;批量注销被描述为批量状态替换行为。
  • 清理:包括心跳过期、连接断连释放、空 service 清理、过期元数据清理,且清理必须发布与正常流程同类的资源事件。

9.2 健康检查与保护

健康检查与保护规范 将healthy与enabled区分开:healthy由心跳/主动健康检查/手动更新(仅 checker 为 NONE 时)/节点间同步驱动;enabled控制是否允许接收发现流量,disabled 实例不应返回给运行时 Open API 消费者。

临时服务的健康由运行时 publisher 存活驱动:HTTP 与兼容客户端通过上报心跳维持存活,Beat check task 依据 last heartbeat time 判断超时;心跳时间可由保留元数据 key 自定义:

Key含义
preserved.heart.beat.interval期望心跳间隔
preserved.heart.beat.timeout实例被视为 unhealthy 前的超时时间
preserved.ip.delete.timeout实例可被删除前的超时时间

持久服务则由服务端健康检查 processor 主动检查,内置 checker 类型包括 TCP、HTTP、MySQL 和 NONE,额外类型通过 health checker registry 注册。保护阈值机制:在 cluster、enabled、内部过滤和 health 过滤后,如果健康比例小于等于protectThreshold,服务端会标记达到保护阈值,返回更宽的过滤实例集合,并把 unhealthy 实例表现为 healthy——保护阈值是发现可用性保护机制,不表示底层实例真实健康。

9.3 发现、订阅与 failover

发现与订阅规范 定义了查询返回的ServiceInfo视图(含 service name、groupName、clusters、cache duration、last reference time、hosts 和保护阈值状态)以及过滤链:cluster 过滤、enabled-only 过滤、health-only 过滤、服务端内部过滤规则、保护阈值。

gRPC 订阅在调用方连接下记录 subscriber 并返回当前视图,后续变化推送;Java SDK 会尽可能将同一 service 的多个本地 listener 映射成一个服务端订阅。模糊订阅通过serviceName和groupNamepattern 订阅 service key,服务端维护 pattern -> watched clients 与 pattern -> 匹配 service keys,存在数量限制。failover 模式下 SDK 可优先读取本地 failover 数据,它是客户端应急视图,不得改变服务端资源模型。

9.4 一致性路径:临时 AP 与持久 CP

一致性与客户端状态规范 是理解 Naming 内部架构的核心:Naming Client 是服务端对运行时通信参与方数据的抽象,gRPC 一个存活连接对应一个 connection-based Client;HTTP 兼容客户端可创建 IP-port-based Client;携带稳定 Client id 的新 HTTP 契约使用HttpConnectionBasedClient,内部 Client id 为HTTP_CLIENT@@<externalClientId>。

发布到推送的主链路为:

  1. 注册、注销、订阅或取消订阅请求更新 Client;
  2. Client 更新产生 Naming 事件;
  3. service 到 publisher、service 到 subscriber 的索引根据事件更新;
  4. 通过索引从 publisher Clients 聚合 service 数据;
  5. 通过索引筛选订阅同一 service 的 subscriber Clients;
  6. gRPC push 通过每个 subscriber 连接发送聚合后的ServiceInfo视图。

临时服务走偏 AP 路径(Distro client data 同步),持久服务走偏 CP 路径(persistent service group + snapshot),订阅属于临时 client 行为(持久 client 不支持 subscriber state)。

临时服务 Distro 一致性规范 进一步明确了 ownership 规则(connection-based client 由持有连接的节点拥有,IP-port client 由 Distro responsibility 选出)、变更传播(client changed ->CHANGE、disconnected ->DELETE、verify failed ->ADD)、verify 与 anti-entropy(revision 匹配刷新 liveness,不匹配触发 repair,snapshot 是整数据类型的 anti-entropy),以及最终一致性的可见性链条:owner 更新 -> 本地事件更新索引 -> Distro sync -> peer apply -> service change event 调度 push。

持久服务 CP 一致性规范 定义了三个独立 CP group:Constants.NAMING_PERSISTENT_SERVICE_GROUP_V2(持久实例发布状态)、Constants.SERVICE_METADATA(service 和 cluster metadata)、Constants.INSTANCE_METADATA(instance metadata)。持久实例写入序列化为 instance store request 提交到 persistent group;metadata 写入保留 service type 字段;snapshot 恢复按"更新已有 client / 创建缺失 client / 移除多余 client / 产生修复事件"四步执行。失败行为上,CP group 无可用 leader 时必须失败,不得 fallback 到 Distro,持久 batch registration 和 persistent subscription 均不支持。

10. 相关规范速查

  • Naming 临时服务 Distro 一致性规范
  • Naming 持久服务 CP 一致性规范
  • 运行时推送与重连规范
  • AP 一致性规范
  • CP 一致性规范
  • 内部 RPC 与集群请求规范
  • Naming 目录 README(规范全景图)

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询