序
最近一口气发布好几个服务,涉及大约9个实例同时更新,而总共有16个服务实例注册,出现了eureka开启自我保护模式,过了好几分钟还没有恢复。
分析
设定的eureka.instance.leaseRenewalIntervalInSeconds为10秒。eureka为2个实例,eureka.server.renewalPercentThreshold为0.85,而eureka.server.renewalThresholdUpdateIntervalMs为900000。
按这么算,正常的阈值为27,而当9个服务重启,则瞬间注册的实例为16+9=25,那么此时阈值就更新为42,而启动的时候,旧的9个实例相续关闭,而新的9个实例相续还没有启动起来,那么实际每分钟能发送心跳的数为7*6=42.
是否开启自我保护
eureka-core-1.4.12-sources.jar!/com/netflix/eureka/registry/PeerAwareInstanceRegistryImpl.java
@Override
public boolean isLeaseExpirationEnabled() {
if (!isSelfPreservationModeEnabled()) {
// The self preservation mode is disabled, hence allowing the instances to expire.
return true;
}
return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
}
最近1分钟收到的心跳数没有大于阈值,那么这个时候,就开启自我保护了。
小结
这个有点类似惊群问题(thundering herd):
同理,对于使用eureka作为服务发现的应用来说,在部署生产的要十分小心,要么每次部署的实例不要太多,要么修改eureka的相关参数,比如renewalPercentThreshold或者renewalThresholdUpdateIntervalMs。