最近一口气发布好几个服务,涉及大约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。


03-05 19:21