目录
[1. 客户端与服务端之间的一致性 (最终一致性)](#1. 客户端与服务端之间的一致性 (最终一致性))
[2. 服务端节点之间的一致性 (分布式存储一致性)](#2. 服务端节点之间的一致性 (分布式存储一致性))
下面详细介绍 Nacos 1.x 服务发现模块及其数据一致性实现(涵盖客户端-服务端、服务端节点间):
一、服务发现模块核心机制
Nacos 服务发现的核心是 ServiceManager
和 Client
交互:
- 服务注册 (Registration):
-
- 客户端 (服务提供者) 启动时,通过 HTTP/gRPC 向 Nacos Server 发送注册请求,包含自身实例信息 (IP, Port, 元数据, 集群名, 分组等)。
- Nacos Server 的
InstanceController
接收请求,调用ServiceManager
。 ServiceManager
在内存 (ConcurrentHashMap<String, Service>
) 中创建或找到对应的Service
对象,将Instance
添加到该 Service 的实例列表 (Cluster
) 中。- 触发
ServiceChangeEvent
事件,通知订阅了该服务的客户端。
- 服务发现 (Discovery):
-
- 客户端 (服务消费者) 启动时,通过 HTTP/gRPC 向 Nacos Server 查询指定服务名的所有健康实例列表。
- Nacos Server 的
InstanceController
处理查询,ServiceManager
从内存中获取对应Service
的实例列表,根据健康状态过滤后返回。 - 客户端通常会缓存这份初始列表。
- 服务订阅与推送 (Subscription & Push):
-
- 客户端在获取初始列表后,会向 Nacos Server 订阅该服务的变更。
- Nacos Server 将订阅关系存储在内存 (
ClientManager
/SubscriberServiceV1Impl
)。 - 当服务的实例发生注册、注销、健康状态变更 时,
ServiceManager
触发ServiceChangeEvent
。 PushService
监听到事件,遍历该服务的所有订阅者 (客户端),通过 UDP 或 gRPC 长连接 向客户端推送变更通知 (只包含变更的服务名)。- 客户端收到推送通知后,主动发起一次HTTP 查询 请求 (
GET /nacos/v1/ns/instance/list
) 获取该服务最新的全量实例列表,并更新本地缓存。
- 健康检查 (Health Check):
-
- 客户端心跳 (Client Beat): 注册成功的客户端会定期 (默认 5 秒) 向 Nacos Server 发送心跳 (HTTP
PUT /nacos/v1/ns/instance/beat
) 证明自己存活。BeatReactor
处理心跳。 - 服务端主动探测 (Server-Side Check): 如果客户端超过一定时间 (默认 15 秒) 未发送心跳,Nacos Server 的健康检查线程 (
HealthCheckReactor
) 会主动探测该实例 (TCP/HTTP/MYSQL/TTL)。探测失败则标记实例为unhealthy
或直接删除。ClientBeatCheckTask
监控心跳超时。
- 客户端心跳 (Client Beat): 注册成功的客户端会定期 (默认 5 秒) 向 Nacos Server 发送心跳 (HTTP

二、数据一致性实现
1. 客户端与服务端之间的一致性 (最终一致性)
- 核心目标: 确保客户端本地缓存的实例列表尽可能接近 Nacos Server 内存中的真实状态。
- 实现机制:
-
- 心跳维持租约 (Lease): 客户端心跳相当于续租。服务端认为最近心跳时间 + 超时时间内的实例是健康的。超时未续租的实例会被标记或删除。
- 服务端主动健康检查: 作为心跳的兜底机制,确保即使客户端异常退出(无法发送注销请求),服务端也能探测到并清理无效实例。
- 变更推送 + 主动查询: UDP/gRPC Push 通知及时性高 但可能丢失(尤其是UDP)。客户端收到通知后主动发起的 HTTP 查询是可靠的获取最新数据的保证。
- 客户端定时轮询兜底: 即使推送完全失败,客户端也会定时 (默认 30 秒) 主动发起 HTTP 查询 (
GET /nacos/v1/ns/instance/list
) 来刷新本地缓存,确保最终一致。
- 一致性模型: 最终一致性。从实例变更(注册/注销/健康状态变化)发生到所有订阅的客户端感知到变更,存在短暂延迟(通常在秒级)。推送的及时性和心跳/轮询的间隔决定了不一致窗口的大小。
2. 服务端节点之间的一致性 (分布式存储一致性)
- 核心目标: 在 Nacos 集群部署时,确保所有节点内存中存储的同一服务的实例信息最终相同。
- 实现机制 (Distro 协议 - AP 模式): Nacos 服务发现默认采用自研的 Distro 协议 ,这是一个 AP (Availability, Partition tolerance) 优先的、最终一致性的分布式协议。
-
- 数据分片与责任节点: Distro 协议将集群中所有服务的实例数据虚拟分片 。每个 Nacos 节点被设计为负责一部分服务数据的"责任节点 "。责任分配基于一致性哈希 算法(如
VirtualNode
),通常使用服务名(Service Name
) + 集群名(Cluster Name
) 作为哈希 Key。 - 写操作流程 (注册/注销):
- 数据分片与责任节点: Distro 协议将集群中所有服务的实例数据虚拟分片 。每个 Nacos 节点被设计为负责一部分服务数据的"责任节点 "。责任分配基于一致性哈希 算法(如

-
-
- 当客户端向某个 Nacos 节点 (Node A) 发起注册/注销请求时:
-
-
-
-
- 如果 Node A 是该服务数据的责任节点,则:
-
-
-
-
-
-
- 在本地内存中执行实例的添加/删除/更新操作。
- 将操作写入本地磁盘文件 (
data/protocol/
) 进行持久化(用于重启恢复,不是主存储)。 - 触发
ServiceChangeEvent
(引发后续的客户端推送)。 - 异步 地将此变更数据 通过 HTTP 请求批量复制 (
DistroHttpAgent
) 给集群中的所有其他节点 (Node B, Node C...)。
-
-
-
-
-
-
- 如果 Node A 是非责任节点 ,它会将请求重定向 (HTTP 307) 或代理转发 给该服务数据的责任节点 (Node X)。由 Node X 执行上述责任节点的操作。
-
-
-
- 读操作流程 (查询):

-
-
- 客户端向任意节点 (Node Y) 发起查询请求。
- Node Y 直接查询自己本地内存中存储的该服务实例数据并返回给客户端。
- 关键点: 非责任节点 (Node Y) 本地存储的数据可能滞后 于责任节点 (Node X) 的数据,因为它依赖于 Node X 的异步复制。这是实现高可用 (任何节点都可读)和低延迟 (本地读)的代价,导致读取可能不是强一致的。
-
-
- 数据同步 (健康检查与修复):
-
-
- 定时同步摘要 (Checksum): 每个节点定期 计算自己负责的所有服务的实例列表的校验和 (Checksum),并将这些摘要信息发送给集群中的其他节点。
- 校验和比对: 节点收到其他节点的摘要信息后,会与自己计算的摘要进行比对。
- 差异拉取 (Sync): 如果发现某个服务的校验和不匹配(表明数据不一致),节点会主动向持有该服务最新数据的节点(通常是责任节点)发起 HTTP 请求 ,拉取该服务的全量实例数据 (
GET /nacos/v1/ns/distro/datum
) 来覆盖本地数据,完成修复。 - 新节点加入/重启: 新加入的节点或重启恢复的节点,会主动向集群中其他节点拉取其负责的数据分片的全量数据 (
GET /nacos/v1/ns/distro/datums
) 进行初始化。
-
-
- 健康探测: Distro 节点间通过轻量级的心跳互相探测可用性,用于判断节点是否存活,影响数据同步和重定向。
- 一致性模型: 最终一致性 (Eventual Consistency) 。Distro 协议优先保证可用性 (A) 和分区容错性 (P)。
-
- 在网络分区发生时,不同分区的节点仍然可以独立处理自己责任分片内的读写请求(可能导致数据冲突)。
- 异步复制 和定时校验同步机制保证了在网络恢复后,数据最终会达成一致。
- 在无分区的正常情况下,数据复制延迟决定了节点间的不一致窗口(通常很小,毫秒到秒级)。
- 与 CP 模式对比: Nacos 配置中心 模块支持基于 Raft 算法的 CP 模式(需要强一致性)。但服务发现 模块默认且主要 使用 AP 模式的 Distro 协议。这是由服务发现的场景特点决定的:服务实例频繁上下线,对可用性要求极高,短暂的数据不一致(如某个节点短暂显示一个刚下线的实例)通常是可以容忍的。用户可以通过
nacos.standalone=false
+nacos.member.list
配置集群,并确保所有节点使用相同的 Distro 实现(默认内置)。
总结
- 服务发现流程: 围绕
ServiceManager
进行实例存储,通过注册、心跳、订阅、推送+查询、主动健康检查实现动态管理。 - 客户端-服务端一致性 (最终一致): 依赖心跳租约 、服务端健康检查兜底 、变更推送触发主动查询 、客户端定时轮询兜底 共同保证客户端缓存最终与服务端状态一致。
- 服务端节点间一致性 (最终一致 - AP): 基于 Distro 协议 。通过数据分片与责任节点 、写请求路由/转发 、责任节点本地处理+异步复制 、任意节点本地读取 、定时校验和比对+差异数据拉取 等机制,在保证高可用和分区容错的前提下,实现数据的最终一致性。这是 Nacos 服务发现高可用架构的核心。