Nacos - 服务注册

Nacos 的服务注册是其核心功能之一。随着版本的演进,Nacos 经历了从 1.x(基于 HTTP)到 2.x(基于 gRPC)的架构升级。

下面我将从客户端发送请求服务端处理请求心跳维持与健康检查三个维度,详细讲解 Nacos(以 2.x 版本为主,兼顾 1.x 区别)的服务注册流程。


一、 整体流程概览

  1. 服务启动:客户端(微服务)启动,读取配置。
  2. 建立连接:客户端与 Nacos 服务端建立长连接(gRPC)。
  3. 发送注册请求:客户端封装实例信息(IP、Port、服务名等)发送给服务端。
  4. 服务端存储:服务端将实例信息存入内存注册表。
  5. 数据同步:服务端将新注册的实例信息同步给集群内的其他 Nacos 节点(Distro 协议)。
  6. 服务变更通知:服务端主动推送最新的服务列表给订阅了该服务的客户端。

二、 详细步骤解析

1. 客户端:发起注册 (Client Side)

  • 入口 :在 Spring Cloud 环境下,注册入口是 NacosServiceRegistry.register() 方法。
  • 封装实例 :构造 Instance 对象,包含:
    • Service Name(服务名)
    • IPPort
    • Weight(权重)
    • Metadata(元数据)
    • Ephemeral(是否是临时实例,默认 true
  • 通信协议
    • Nacos 1.x :通过 HTTP POST 请求发送到 /nacos/v1/ns/instance
    • Nacos 2.x :通过 gRPC 传输。客户端通过 NamingClientProxy 调用 registerService,请求会被封装成 InstanceRequest 发送。

2. 服务端:接收与存储 (Server Side)

当 Nacos 服务端收到注册请求后,会执行以下逻辑:

  • 解析请求InstanceRequestHandler 接收 gRPC 请求(1.x 是 InstanceController)。
  • 内存注册表维护
    • Nacos 内部维护了一个多层的 Map 结构: Map<namespace, Map<group::serviceName, Service>>
    • Service 类中包含多个 Cluster(集群)。
    • Cluster 中维护了两个 Set<Instance>:一个是 临时实例 ,一个是 持久化实例
  • 写时复制 (CopyOnWrite) :为了防止高并发下的读写冲突,Nacos 在更新实例列表时采用了类似 CopyOnWrite 的机制。它会先读取旧的列表,创建一个新列表,把新实例放进去,最后替换旧列表。

3. 服务端:一致性协议 (Consistency)

Nacos 根据实例类型(临时/持久化)走不同的协议:

  • 临时实例(默认,AP模式)
    • 使用 Distro 协议(Nacos 自研)。
    • 注册节点会立即同步给集群内其他节点。
    • 遵循 最终一致性,保证高可用。
  • 持久化实例(CP模式)
    • 使用 Raft 协议(JRaft 实现)。
    • 必须过半数节点写入成功才算注册成功。
    • 保证 强一致性

4. 服务端:推送通知 (Push)

  • 一旦注册表发生变化,服务端会触发 ServiceChangeEvent
  • 推送机制 :服务端通过 PushService 找到所有订阅了该服务的客户端,通过 gRPC(2.x)或 UDP(1.x)将最新的实例列表推送过去。
  • 客户端缓存 :客户端收到更新后,会更新本地的 ServiceInfo 缓存,从而实现负载均衡时拿到最新的地址。

三、 核心:健康检查机制

注册流程完成后,如何保证服务一直"在线"?

  1. Nacos 1.x (HTTP + 心跳)

    • 客户端每隔 5秒 发送一次心跳(Beat)。
    • 服务端若 15秒 没收到心跳,标记为不健康。
    • 30秒 没收到心跳,直接剔除实例。
  2. Nacos 2.x (gRPC + 连接探测)

    • 长连接 :基于 gRPC 的 Stream。如果客户端宕机,gRPC 连接会断开。
    • 连接断开即剔除:服务端监控连接状态,一旦连接异常断开(Connection Disconnect),服务端会立即触发下线流程(针对临时实例)。这种方式比心跳更实时。

四、 总结:1.x 与 2.x 的关键区别

特性 Nacos 1.x Nacos 2.x
通信协议 HTTP gRPC (双向流)
注册效率 每次注册/心跳都是短连接,开销大 长连接复用,极大减少连接握手消耗
实时性 依赖心跳间隔,响应稍慢 连接断开瞬时感应,响应极快
一致性协议 Distro (AP) / Raft (CP) 优化后的 Distro / JRaft

总结口述版

"Nacos 注册流程首先是客户端通过 gRPC(2.x)向服务端发起注册请求。服务端接收后,会将实例信息存入内存中的双层 Map 结构中,并根据实例是否是临时的,选择走 Distro 异步同步(AP)或 Raft 强一致同步(CP)。存储完成后,服务端会发布变更事件,通过长连接异步推送给所有订阅该服务的客户端。最后,通过 gRPC 的长连接状态来维持实例的健康状态,一旦断开则自动剔除。"

相关推荐
曲莫终13 小时前
Java VarHandle全面详解:从入门到精通
java·开发语言
一心赚狗粮的宇叔13 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
奋进的芋圆13 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
计算机程序设计小李同学14 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
小途软件14 小时前
用于机器人电池电量预测的Sarsa强化学习混合集成方法
java·人工智能·pytorch·python·深度学习·语言模型
alonewolf_9914 小时前
Spring MVC启动与请求处理全流程解析:从DispatcherServlet到HandlerAdapter
java·spring·mvc
Echo娴14 小时前
Spring的开发步骤
java·后端·spring
吴声子夜歌14 小时前
Java数据结构与算法——基本数学问题
java·开发语言·windows
_UMR_15 小时前
springboot集成Jasypt实现配置文件启动时自动解密-ENC
java·spring boot·后端