Eureka自我保护机制

目录

         Eureka自我保护机制

​自我保护开启条件

自我保护阀值的计算

自我保护阀值的计算公式

自我保护逻辑

自我保护开关

开发环境配置


 

Eureka注册中心中各个Eureka-Server节点都是平等的,没有ZK中角色的概念,即使N-1个节点挂掉也不会影响其他节点的正常运行。Eureka-Server可以很好的应对因网络故障导致部分节点失联的情况,而不会像ZK那样如果有一半不可用的情况会导致整个集群不可用而变成瘫痪。

Eureka自我保护机制是为了防止误杀服务导致系统瘫痪而提供的一个机制。

何为误杀?

理论上每个服务都有故障的可能,那么自然Eureka注册中心也有故障的可能性。如果注册中心发生故障,服务就有可能不能正常续约,或者当网络分区故障发生时,微服务与Eureka-Server之间无法正常通信,而这个时候服务仍然是可以正常服务的,如果Eureka剔除任务将其剔除,则会造成误杀。

怎么判断Eureka Server故障了?

Eureka Server以一种谦虚的态度来判断是不是自己出了问题,也就是当大量的服务续约超时时,就认为是自己出现问题了。(如果少量服务续约超时,则认为是服务故障)

Eureka自我保护机制

自我保护开启条件

Eureka-Server通过判断是否有大量续约失败,来确定是否开启自我保护。这里提供了一个阀值numberOfRenewsPerMinThreshold和上一分钟的续约数进行对比,如果实际的续约数小于了自我保护阀值,则开启自我保护。


 
  1. public boolean isLeaseExpirationEnabled() {
  2. if(!isSelfPreservationModeEnabled()) {
  3. // The self preservation mode is disabled, hence allowing the instances to expire.
  4. return true;
  5. }
  6. return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
  7. }

 

自我保护阀值的计算

有三个地方会重新计算自我保护阀值numberOfRenewsPerMinThreshold。

1、当新服务注册(register)时


 
  1. synchronized (lock) {
  2. if ( this.expectedNumberOfClientsSendingRenews > 0) {
  3. // Since the client wants to register it, increase the number of clients sending renewsthis.
  4. expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews + 1;updateRenewsPerMinThreshold();
  5. }
  6. }

2、当服务退出(cancel)时


 
  1. public boolean cancel(final String appName, final String id, final boolean isReplication) {
  2. if ( super.cancel(appName, id, isReplication)) {
  3. replicateToPeers(Action.Cancel, appName, id, null, null, isReplication);
  4. synchronized (lock) {
  5. if ( this.expectedNumberOfClientsSendingRenews > 0) {
  6. // Since the client wants to cancel it, reduce the number of clients to send renewsthis.
  7. expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews - 1;
  8. updateRenewsPerMinThreshold();
  9. }
  10. }
  11. return true;
  12. }
  13. return false;
  14. }

3、TimerTask定时任务(默认15分钟)


 
  1. /*** Schedule the task that updates <em>renewal threshold</em> periodically.
  2. * The renewal threshold would be used to determine if the renewals drop
  3. * dramatically because of network partition and to protect expiring too
  4. * many instances at a time.**/
  5. private void scheduleRenewalThresholdUpdateTask() {
  6. timer.schedule( new TimerTask() {
  7. @Override
  8. public void run() {
  9. updateRenewalThreshold();
  10. }
  11. }, serverConfig.getRenewalThresholdUpdateIntervalMs(),
  12. serverConfig.getRenewalThresholdUpdateIntervalMs());
  13. }

 

自我保护阀值的计算公式


 
  1. protected void updateRenewsPerMinThreshold() {
  2. this.numberOfRenewsPerMinThreshold = ( int) ( this.expectedNumberOfClientsSendingRenews
  3. * ( 60.0 / serverConfig.getExpectedClientRenewalIntervalSeconds())
  4. * serverConfig.getRenewalPercentThreshold());
  5. }

自我保护阀值 = 服务总数 * 每分钟续约数 * 自我保护续约百分比阀值因子。

每分钟续约数 =(60S/客户端续约间隔)

最后自我保护阀值的计算公式为:

自我保护阀值 = 服务总数 * (60S/客户端续约间隔) * 自我保护续约百分比阀值因子。

备注:在老版本中阀值的计算有点错误,新版本中修复成现在的计算公式。

自我保护逻辑

Eureka Server提供了一个EvictionTask定时清理续约超时的服务。清理之前首先判断是否需要清理(isLeaseExpirationEnabled())。这个判断方法首先会判断是否开启了自我保护开关,如果开启了,则会继续判断上一分钟的续约数是否小于自我保护阀值,如果上一分钟的续约数(numOfRenewsInLastMin)小于自我保护阀值(numberOfRenewsPerMinThreshold),则开启自我保护机制,不再进行服务的剔除。


 
  1. public boolean isLeaseExpirationEnabled() {
  2. if (!isSelfPreservationModeEnabled()) {
  3. // The self preservation mode is disabled, hence allowing the instances to expire.
  4. return true;
  5. }
  6. return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
  7. }

备注1:numberOfRenewsPerMinThreshold是对所有服务总阀值的计算,而不是单个服务的计算。

备注2: Eureka默认的自我保护阀值因子是85%,可以通过renewalPercentThreshold修改。

 

自我保护开关

Eureka自我保护机制,通过配置eureka.server.enable-self-preservation来true打开/false禁用自我保护机制,默认打开状态,建议生产环境打开此配置。

 

开发环境配置

开发环境中如果要实现服务失效能自动移除,只需要修改以下配置。

1、 注册中心关闭自我保护机制,修改检查失效服务的时间。


 
  1. eureka:
  2. server:
  3. # 该配置可以移除这种自我保护机制,防止失效的服务也被一直访问 (Spring Cloud默认该配置是 true)
  4. enable-self-preservation: false
  5. #该配置可以修改检查失效服务的时间,每隔 30s检查失效服务,并移除列表 (Spring Cloud默认该配置是 60s)
  6. eviction-interval- timer- in-ms: 3000

2、 微服务修改减短服务心跳的时间。


 
  1. # 告知服务端30秒还未收到心跳的话,就将该服务移除列表,默认90秒
  2. lease-expiration-duration- in-seconds: 30
  3. # 每隔10s发送一次心跳,默认30秒
  4. lease-renewal-interval- in-seconds: 10

以上配置建议在生产环境使用默认的时间配置。

 

Spring Cloud实战项目Jbone地址

github地址:https://github.com/417511458/jbone

码云地址:https://gitee.com/majunwei2017/jbone

 

转自:majunwei - 深入理解Eureka - Eureka自我保护机制

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页