Nacos注册中心心跳机制|🪼的便签

77 阅读2分钟

Intro

Nacos作为服务注册中心,支持两种实例类型

  • 临时实例 Ephemeral (默认)
  • 持久化实例 Persistent

心跳机制有什么用呢?它主要用于临时实例的健康检查,确保注册中心能及时感知到实例的存活状态

1 临时实例的心跳机制

client主动上报心跳+server健康检查

1.1 client

客户端实例注册后,会启动一个定时任务,每隔固定时间间隔,就会向Nacos server发送Beat,就是心跳包。默认心跳间隔一般是5s,可以自定义。

心跳的内容就是实例信息,IP,port,权重,元数据等。

  • 在Nacos 1.x版本,是通过HTTP PUT请求 /nacos/v1/ns/instance/beat发送。容易产生大量请求。
  • Nacos 2.x版本则切换为gRPC长链接,利用连接本身的保活机制+服务端主动去检测。
sequenceDiagram
    participant Client
    participant Server
    Client->>Server: 注册实例 (gRPC 连接)
    loop 每隔一段时间
        Client->>Server: 连接保活 (keepalive)
    end
    Note over Server: 定时检查无数据连接 >20s → 剔除

1.2 server

服务端接收到心跳后,更新实例的最后心跳时间 lastBeat。服务端也启动了一个定时任务,每5s检查一次,超过15s未收到心跳,标记该实例为不健康。

healthy = false

超过30s没收到,直接从服务列表中删除。这保证实例异常下限可以被快速感知到。

Nacos2.x

// ConnectionManager.start()
executor.scheduleWithFixedDelay(() -> checkConnections(), 3, 3, TimeUnit.SECONDS);

private void checkConnections() {
    for (Connection conn : connections) {
        if (System.currentTimeMillis() - conn.getLastActiveTime() > 20_000) {
            // 标记过期,探活失败则 unregister instances
        }
    }
}

2持久化实例的健康检查

持久化实例不依赖client的心跳,而是服务端主动检测,有三种检测模式:TCP,HTTP,或者MySQL,TCP是默认方式。异常时仅标记为不健康,不会剔除实例,比较适合DNS场景。

3 配置心跳超时时间

想自定义快速上下线,觉得默认的30s剔除太慢,我们就可以通过实例的metadata配置来缩短这个时间。

spring:
  cloud:
    nacos:
      discovery:
        metadata:
          preserved.heart.beat.interval: 5000   # 心跳间隔(毫秒,默认 5000)
          preserved.heart.beat.timeout: 15000   # 心跳超时(毫秒,默认 15000)标记不健康
          preserved.ip.delete.timeout: 30000    # 实例删除超时(毫秒,默认 30000) 剔除实例
          

最后:为什么需要心跳机制

心跳是Nacos实现高可用的核心机制。正常下线的话,客户端会主动发送注销请求。如果客户端异常下线,比如进程崩溃,服务端收不到心跳,就会自动标记,剔除,避免调用不可用的实例。

Nacos的心跳设计是借鉴了Eureka的,它比Eureka更灵活,支持AP/CP的切换。如果生产环境需要更快的响应,我们也可以自定义metadata配置。