• 自我保护机制是什么?
    在eureka server中,他假定正常情况下肯定有大于85%的服务实例能够保持正常的心跳,最近1分钟内少于85%的服务实例心跳成功,eureka开发团队认为,此时大概率是eureka server自己的网络故障了,此时再进行过期实例剔除都会是误伤,于是就不再对故障实例剔除。这就叫进入了自我保护机制。
  • 自我保护的实现原理

    eureka自我保护机制的代码实现比较零散,逻辑分散的各处,需要仔细翻阅源码才能找到,笔者也是花了几个小时(一个开源项目里的代码质量还真是参差不齐。。。)

    • 在上篇文章讲解的自动摘除服务实例的实现方法evit中,在最开始进行了当前是否进入自我保护状态的判断

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      @Override
      public boolean isLeaseExpirationEnabled() {
      if (!isSelfPreservationModeEnabled()) {
      // The self preservation mode is disabled, hence allowing the instances to expire.
      return true;
      }

      // 如果开启自我保护机制 就会走下面的逻辑

      // numberOfRenewsPerMinThreshold = 服务实例数量 * 2 * 0.85 期望值,最少有85%的实例发送心跳 心跳30秒1次,于是就 *2

      // getNumOfRenewsInLastMin() 返回的就是 最近1分钟实际心跳成功的服务实例数
      // 是通过 MeasuredRate 组件 + renew时触发来实现的

      // 这个判断的意思也就明了了,最近1分钟实际心跳成功的服务实例数 > 要大于85% ,这个时候才会允许处理过期服务实例

      // 为啥这么做?
      // 这也就是eureka所谓的自我保护机制的实现了。他假定正常情况下肯定会有超过85%的服务实例能够心跳成功成功的
      // 如果小于85%,那么就有可能是eureka server自己的网络出现故障了,此时就不能再剔除过期实例了,因为可能是误伤
      // 这种状态下不剔除服务实例,这个操作,就是进入自我保护模式这个动作,达到了自我保护这个状态和效果,此时eureka控制台里也会显示出那行红字

      // 为什么测试环境非常容易触发自我保护机制呢?
      // 测试环境频繁的有服务实例注册、销毁,生命周期非常的短,可能连第二次心跳都没进行,这就导致最近一分钟内的服务实例心跳成功数大大降低
      // 非常有可能低于85%,一旦低于85%就会进入自我保护模式。
      // 测试环境这种情况是持续存在的,所以就会显示出eureka持续进入自我保护模式了

      // 这个方法 返回true,说明正常;返回false,就是进入了自我保护模式了
      // 这点儿注意,与Spring cloud netflix eureka的实现方式相同,但返回值的含义是相反的
      return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
      }
      • numberOfRenewsPerMinThreshold 服务实例数量 * 2 * 0.85 期望值,最少有85%的实例发送心跳 心跳30秒1次,于是就 *2

      • getNumOfRenewsInLastMin() 返回的就是 最近1分钟实际心跳成功的服务实例数
        是通过 MeasuredRate 组件 + renew时触发来实现的
        也就是每次心跳成功都会对MeasuredRate 内的数值加1,而每隔1分钟,MeasuredRate 组件会把自己的数值清零

      • 如果 getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold,也就是最近1分钟,少于85%的服务实例心跳成功,就意味着进入了自我保护状态了

        这个方法 返回true,说明正常;返回false,就是进入了自我保护模式了

        注意,与Spring cloud netflix eureka的实现方式相同,但返回值的含义是相反的

  • 为什么测试环境非常容易触发自我保护机制呢?
    测试环境频繁的有服务实例注册、销毁,生命周期非常的短,可能连第二次心跳都没进行,这就导致最近一分钟内的服务实例心跳成功数大大降低,非常有可能低于85%,一旦低于85%就会进入自我保护模式。 测试环境这种情况是持续存在的,所以就会显示出eureka持续进入自我保护模式了

注意

自我保护机制的实现,采用了硬编码的方式强制指定了30秒的心跳周期,所以在实际生产中,我们要么不用这个自我保护模式,要么就不要修改心跳间隔,否则逻辑就错乱了

总结

eureka自我保护机制

Comments