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 -> serviceNameCluster 和 Instance 是从属资源:
namespaceId -> groupName -> serviceName -> clusterName -> instance2.1 Service 身份字段
| 字段 | 含义 | 说明 |
|---|---|---|
namespaceId | 服务所属 namespace | 当接口支持默认值处理时,空值或缺省值会被处理为默认 namespace id |
groupName | namespace 内的业务分组 | 新公开规范和 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:由 instance
ip、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 状态、索引和 snapshot | Naming 一致性与客户端状态规范 |
| 临时服务 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 type
Nacos: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>。
发布到推送的主链路为:
- 注册、注销、订阅或取消订阅请求更新 Client;
- Client 更新产生 Naming 事件;
- service 到 publisher、service 到 subscriber 的索引根据事件更新;
- 通过索引从 publisher Clients 聚合 service 数据;
- 通过索引筛选订阅同一 service 的 subscriber Clients;
- 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),仅供参考