文章目录

  • Eureka 健康检查
  • Eureka 心跳续约和逐出
  • Eureka Client 心跳续约
  • Eureka Server 心跳逐出
  • 更新实例续约时间
  • 统计逐出过期实例



Eureka Client心跳和健康检查分别在独立的线程内,心跳和健康检查属于不同的功能机制。

Eureka 健康检查

Eureka Client会不断的通过健康检查判断自身客户端的健康状况,默认为30s。当状态变更时将自身的状态更新eureka server

Eurekaspring cloud体系里健康检查主要分为2类:

  1. 参数 eureka.client.healthcheck.enabledtrue下的spring cloud eureka微服务健康检查
  2. 上述参数为false或者直接使用eureka(未使用spring cloud)体系下的健康检查

下图内左侧为类别2的健康检查机制,右侧为类别1的健康检查机制。

java 心跳检测ip是否在线 spring cloud 心跳检测_java 心跳检测ip是否在线

  1. eureka根据客户端的status值作为健康检查结果,默认情况(也就是类别2)下eureka clientstatus不会被自己修改,他的stauts正常情况下一直是初始化客户端时配置的值,比如初始化构建eureka client设置的statusUP,那么健康检查值一直为UP
  2. 在类别1eureka client健康检查机制会集成spring actuator health健康检查机制。如果spring actuator健康检查结果为DOWN,会导致eureka client实例状态改为DOWN

Eureka Client健康状态发生变更时,客户端会触发更新机制,将最新的状态发送给eureka server。基于健康检查机制,服务端更新实例健康状态,保证实例状态为DOWN不被服务发现。

java 心跳检测ip是否在线 spring cloud 心跳检测_java 心跳检测ip是否在线_02

Eureka 心跳续约和逐出

Eureka Client 心跳续约

Eureka Client专门有一个Thread用于心跳,30s触发一次。心跳线程com.netflix.discovery.DiscoveryClient.HeartbeatThread,用于续约。

客户端心跳会将client状态发送到server端,看着客户端代码会认为服务端通过心跳更新了server端实例状态,但是在服务端代码里client心跳上传的状态未被使用,所以心跳只用来续约,不会更新服务端实例的状态。

Eureka Client心跳的主要流程

  1. 客户端发送心跳。
  2. 服务端响应吗为200,续约成功。
  3. 如果服务端响应吗为404,客户端重新注册。
  4. 注册成功则续约成功。
  5. 否则续约失败。

java 心跳检测ip是否在线 spring cloud 心跳检测_服务端_03

Eureka Server 心跳逐出

如果未开启自我保护机制,根据统计结果剔除过期实例。

如果开启自我保护机制,最后一分钟内续约个数 <= 总数*自我保护阈值,放弃剔除。

更新实例续约时间

服务端收到心跳请求处理逻辑:

  1. 判断服务端是否存在心跳来源实例,如果不存在返回404
  2. 更新服务端心跳实例的最后一次续约时间,默认续约时长为90s

更新方式: 最后一次续约时间 = 当前时间戳 + 续约时间(默认90s)

统计逐出过期实例

服务端有一个逐出定时任务,每60s执行一次,用来剔除没有符合预期规则心跳的实例。

服务端剔除实例条件:

当前时间戳 > 最后一次续约的时间 + 续约时间(默认90s) + 额外时间

(额外时间含义:2次逐出任务实际执行间隔时间可能和定时任务的配置值不一定完全相同,可能差几毫秒)

官方代码里特意解释了这个公式,计算是否过期的条件其实是被放宽了,因为客户端心跳成功了,最后续约时间会被加上90s,在检查判断剔除条件时,又额外加了90s,相当于如果超过180s没有心跳才会被认为已经过期。

过期实例统计完成后等待后续剔除。