警告!Eureka 可能存在维护了错误的实例列表(当它们没有启动的时候,Eureka 却把它当成启动的了);Renews 值小于 Threshold 值,因此剩下未过期的都是安全的。
原因分析:
这个是 Eureka 的自我保护机制。Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟之内是否低于 85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server 会将当前的实例注册信息保护起来,同时提示这个警告。
Eureka server 和 client 之间每隔 30 秒会进行一次心跳通信,告诉 server,client 还活着。由此引出两个名词:
Renews threshold:server 期望在每分钟中收到的心跳次数
Renews (last min):上一分钟内收到的心跳次数。
前文说到禁止注册 server 自己为 client,不管 server 是否禁止,阈值(threshold)是 1。client 个数为 n,阈值为 1+2n(此为一个 server 且禁止自注册的情况)
如果是多个 server,且开启了自注册,那么就和 client 一样,是对于其他的 server 来说就是 client,是要 2 的
我开了两个 server,自注册,相关数据如下
阈值:1+21
renews:
1)自注册 2 + 21
2)非自注册:2*1
Eurake 有一个配置参数 eureka.server.renewalPercentThreshold,定义了 renews 和 renews threshold 的比值,默认值为 0.85。当 server 在 15 分钟内,比值低于 percent,即少了 15% 的微服务心跳,server 会进入自我保护状态,Self-Preservation。在此状态下,server 不会删除注册信息,这就有可能导致在调用微服务时,实际上服务并不存在。
这种保护状态实际上是考虑了 client 和 server 之间的心跳是因为网络问题,而非服务本身问题,不能简单的删除注册信息
stackoverflow 上,有人给出的建议是:
1、在生产上可以开自注册,部署两个 server
2、在本机器上测试的时候,可以把比值调低,比如 0.49
3、或者简单粗暴把自我保护模式关闭
**`eureka.server.enableSelfPreservation=false`**
参考文档