Nacos 心跳机制与配置变更通知原理详解

4 阅读3分钟

1. Nacos 架构模式概述

Nacos 根据数据一致性的要求,提供了两种模式:

  • AP 模式(可用性优先):使用自研的 Distro 协议,保证高可用和最终一致性。适用于服务注册与发现中的临时实例
  • CP 模式(一致性优先):基于 JRaft 协议,保证强一致性。适用于配置管理及持久化实例

注意:AP/CP 模式并非用户显式配置,而是由实例的 ephemeral 属性决定。临时实例(ephemeral=true)使用 AP 模式,持久化实例(ephemeral=false)使用 CP 模式。


3. AP 模式(临时实例)心跳机制

3.1 1.x 版本:HTTP 短连接 + 客户端主动心跳

  • 通信协议:HTTP 短连接(每次心跳新建连接)。
  • 心跳频率:客户端每 5 秒发送一次 HTTP 心跳请求。
  • 超时剔除
    • 服务端 15 秒未收到心跳 → 标记为不健康(亚健康)
    • 服务端 30 秒未收到心跳 → 立即剔除实例

3.2 2.x 版本:gRPC 长连接 + 客户端主动心

  • 通信协议:gRPC 长连接(基于 HTTP/2),连接复用,减少资源消耗。
  • 心跳机制:客户端仍然每 5 秒通过 gRPC 流发送心跳(Ping 请求)。

2.x 相比 1.x 的优势

  • 消除 HTTP 短连接带来的 TIME_WAIT 堆积。
  • gRPC 双向流支持服务端主动推送,服务变更实时性更高。
  • 降低服务端 TPS 压力,提升整体吞吐量。

4. CP 模式(持久化实例)健康检查机制

持久化实例(ephemeral=false)采用服务端主动探测的方式,适用于地址相对固定的基础设施。

设计初衷

  • 持久化实例通常代表稳定组件(如数据库),不应因短暂网络波动被自动剔除。
  • 即使实例不可用,仍需保留在注册表中,供依赖方知晓其状态(通过 DOWN 状态避免被调用),或在保护阈值下作为兜底节点。

5. 配置变更后通知客户端机制

Nacos 配置中心的变更通知机制在 1.x 与 2.x 版本中有本质区别。

5.1 1.x 版本:HTTP 长轮询(Long Polling)

原理

  1. 客户端通过 HTTP 请求向服务端询问指定配置是否有变更。
  2. 服务端检查配置的 MD5 值:
    • 如果已变更 → 立即返回新配置信息。
    • 如果未变更 → 利用 Servlet 3.0 的 AsyncContext 将请求挂起最多 29.5 秒
  3. 若在此期间配置被修改,服务端发布 LocalDataChangeEvent 事件,唤醒挂起的请求,返回“配置已变更”响应。
  4. 若 29.5 秒内无变更,服务端返回“未变更”响应。
  5. 客户端无论收到何种响应,立即发起下一次长轮询,形成持续监听。

5.2 2.x 版本:gRPC 双向流实时推送

原理

  1. 客户端启动时与服务端建立 gRPC 双向流长连接。
  2. 客户端通过流发送 ConfigBatchListenRequest,向服务端注册关注的配置列表。
  3. 配置变更时,服务端通过 Raft 共识写入后,发布 ConfigDataChangeEvent,触发 RpcConfigChangeNotifier
  4. RpcConfigChangeNotifier 查找订阅了该配置的所有客户端连接,通过 gRPC 流直接推送 ConfigChangeNotifyRequest 通知。
  5. 客户端收到通知后,发起 ConfigQueryRequest 拉取最新配置内容,更新本地缓存,并触发 Listener 回调。

优势

  • 真正实时:毫秒级推送,不再依赖轮询周期。
  • 连接复用:一条连接承载所有配置监听,大幅减少网络开销。
  • 可靠传输:基于 HTTP/2 的 gRPC 提供流控和可靠传输。
  • 双向通信:支持服务端主动推送与客户端上报,扩展性强。