Eureka Client
心跳和健康检查分别在独立的线程内,心跳和健康检查属于不同的功能机制。
Eureka 健康检查
Eureka Client
会不断的通过健康检查判断自身客户端的健康状况,默认为30s
。当状态变更时将自身的状态更新eureka server
。
Eureka
和spring cloud
体系里健康检查主要分为2
类:
- 参数
eureka.client.healthcheck.enabled
为true
下的spring cloud eureka
微服务健康检查 - 上述参数为
false
或者直接使用eureka
(未使用spring cloud
)体系下的健康检查
下图内左侧为类别2
的健康检查机制,右侧为类别1
的健康检查机制。
eureka
根据客户端的status
值作为健康检查结果,默认情况(也就是类别2
)下eureka client
的status
不会被自己修改,他的stauts
正常情况下一直是初始化客户端时配置的值,比如初始化构建eureka client
设置的status
为UP
,那么健康检查值一直为UP
。- 在类别
1
下eureka client
健康检查机制会集成spring actuator health
健康检查机制。如果spring actuator
健康检查结果为DOWN
,会导致eureka client
实例状态改为DOWN
。
当Eureka Client
健康状态发生变更时,客户端会触发更新机制,将最新的状态发送给eureka server
。基于健康检查机制,服务端更新实例健康状态,保证实例状态为DOWN
不被服务发现。
Eureka 心跳续约和逐出
Eureka Client 心跳续约
Eureka Client
专门有一个Thread
用于心跳,30s
触发一次。心跳线程com.netflix.discovery.DiscoveryClient.HeartbeatThread
,用于续约。
客户端心跳会将client
状态发送到server
端,看着客户端代码会认为服务端通过心跳更新了server
端实例状态,但是在服务端代码里client
心跳上传的状态未被使用,所以心跳只用来续约,不会更新服务端实例的状态。
Eureka Client
心跳的主要流程
- 客户端发送心跳。
- 服务端响应吗为
200
,续约成功。 - 如果服务端响应吗为
404
,客户端重新注册。 - 注册成功则续约成功。
- 否则续约失败。
Eureka Server 心跳逐出
如果未开启自我保护机制,根据统计结果剔除过期实例。
如果开启自我保护机制,最后一分钟内续约个数 <= 总数*自我保护阈值,放弃剔除。
更新实例续约时间
服务端收到心跳请求处理逻辑:
- 判断服务端是否存在心跳来源实例,如果不存在返回
404
。 - 更新服务端心跳实例的最后一次续约时间,默认续约时长为
90s
;
更新方式: 最后一次续约时间 = 当前时间戳 + 续约时间(默认90s
)
统计逐出过期实例
服务端有一个逐出定时任务,每60s
执行一次,用来剔除没有符合预期规则心跳的实例。
服务端剔除实例条件:
当前时间戳 > 最后一次续约的时间 + 续约时间(默认90s
) + 额外时间
(额外时间含义:2
次逐出任务实际执行间隔时间可能和定时任务的配置值不一定完全相同,可能差几毫秒)
官方代码里特意解释了这个公式,计算是否过期的条件其实是被放宽了,因为客户端心跳成功了,最后续约时间会被加上90s
,在检查判断剔除条件时,又额外加了90s
,相当于如果超过180s
没有心跳才会被认为已经过期。
过期实例统计完成后等待后续剔除。