Eureka 自我保护模式与健康检查机制

时间:2024-05-19 22:28:37

目录

Eureka 自我保护模式


声明:本文使用的 Spring Cloud 版本为 "Greenwich.RELEASE",对应的 Spring Cloud Netflix Eureka 版本为 2.1.0


Eureka 自我保护模式与健康检查机制

Eureka 自我保护模式

官方关于 Eureka 自我保护的解释:Understanding Eureka Peer to Peer Communication

提取总结一句:Eureka Server 自我保护模式在实际生产环境中,建议直接默认开启即可,不推荐进行关闭。本文的目的旨在更好的理解自我保护模式,以及在平时测试练习的时候可以对其进行关闭。

1、什么是 Eureka Server  自我保护?

1)自我保护工作机制:如果 Eureka Server 在 15 分钟内有超过 85% 的 Eureka Client 都没有正常的发送心跳过来(单机模式时尤为明显),那么 Eureka Server 就认为注册中心与客户端出现了网络故障,Eureka Server 自动进入自我保护机制。

2)这也就是为什么平时使用一个 Eureka Server 与一个 Eureka Client 时,即使手动关闭了 Eureka Client,但是 Eureka Server 主页中“Instances currently registered with Eureka”下面 status 栏仍然显示为 UP。

3)进入自我保护模式后,Eureka Server 的 Spring Eureka 主页会出现如下红色提示信息

Eureka 自我保护模式与健康检查机制

#转为小写看起来更直观
emergency! eureka may be incorrectly claiming instances are up when they're not. 
renewals are lesser than threshold and hence the instances are not being expired just to be safe.
#翻译
紧急情况!Eureka可能错误地声称实例已经启动,而事实并非如此,续约低于阈值,为了安全起见实例不会过期

4、自我保护的原则是:宁可放过,不可杀错!自我保护模式是一种针对网络异常波动的安全保护措施,能使 Eureka 集群更加的健壮、稳定的运行。

2、为什么引入 Eureka Server 自我保护?

1)正常情况(15 分钟内没有超过 85% 的 Eureka Client 都没有正常的发送心跳)下,如果 Eureka Server 在约定时间内(默认90秒)没有接收到某个微服务(Eureka Client)实例的心跳,Eureka Server 将会移除该实例。

2)但当网络分区故障发生时,大面积(甚至所有)微服务(Eureka Client)都与 Eureka Server 之间无法正常通信,而各个微服务本身是能正常运行的,此时注册中心不应该移除这些微服务,所以引入了自我保护机制。

3、Eureka Server  自我保护后会怎么样?

1)Eureka Server 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务(Eureka Client)

2)Eureka Server 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它 Eureake Server 上,保证当前节点依然可用。

3)当网络稳定/恢复后,Eureka Server节点会自动退出自我保护模式,期间新的注册信息会被同步到其它 Eureake Server  节点中。

4、如何开启与关闭自我保护?

1)Eureka Server 自我保护模式默认已经开启,如果需要关闭,则在 Eureka Server 端的全局配置文件可以使用如下属性:

#配置 Eureka Server
eureka:
  server:
      enable-self-preservation: false #关闭自我保护机制,实际生产环境时建议不要关闭
      eviction-interval-timer-in-ms: 5000 #驱逐计时器扫描失效服务的间隔时间(默认为60*1000ms),纯粹为了演示才写上,建议不覆盖使用默认值

2)eureka.server.enable-self-preservation=false 关闭自我保护后,Eureka Server 主页 Spring Eureka 上可以看到如下红色的提示信息。

如果手动再将 Eureka Client 非法关闭,则约 2 分钟后,Eureka Server 主页 Instances currently registered with Eureka 下就会直接将其移除。

THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
#转为小写看起来更直观
the self preservation mode is turned off. this may not protect instance expiry in case of network/other problems.
#翻译
自我保护模式已关闭,如果出现网络/其他问题,这可能无法保护实例过期。

3)eureka.server.eviction-interval-timer-in-ms=5000 修改驱逐计时器扫描失效服务间隔时间后,运行日志可以看到现在每隔 5 秒 EvictionTimer 就会执行一次(以前默认是1分钟才执行一次)。

4)eureka.server.eviction-interval-timer-in-ms 不建议修改,因为即使即使修改了,哪怕是 每隔 1s 执行一次,当手动关闭 Eureka Client 后,注册中心也并不会立马注销此节点,同样要等到约 90 秒左右收不到客户端心跳才会将其移除。

...
2019-03-15 11:54:57.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:02.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:07.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:12.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:17.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:22.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:27.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
...

5、如何修改 Eureka Client 心跳发送间隔时间?

1、作为一个实例,需要定期向注册表发送心跳(通过客户端的 serviceurl),默认间隔时间为 30秒。在实例、服务器和客户机的本地缓存中都具有相同的元数据,因此默认 90 秒内需要至少3次心跳,否则服务器会警告:RENEWALS ARE LESSER THAN THE THRESHOLD(更新低于阈值)

Eureka 自我保护模式与健康检查机制

2)如上所示 Renews threshold 为 3,表示默认 90 秒内应该至少收到 3 次心跳,如果低于此值,则会警告:renewals are lesser than the threshold(更新低于阈值)

3)可以在 Eureka Client 端通过设置 eureka.instance.leaseRenewalIntervalinSeconds 属性来更改心跳发送时间,将其设置为小于 30 的值可以加快将客户机连接到其他服务的过程,在生产环境中,最好还是坚持使用默认值,因为服务器中的内部计算会对租约续订期进行假设。

#配置 Eureka Client
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:[email protected]:8761/eurekaServer_shenZhen/eureka #账号密码必须和服务端提供的一致,ip必须指向服务端
  instance:
    # 租约续订间隔时间(默认30秒),如下所示每间隔 5s 向服务端发送一次心跳,证明自己依然"存活"
    lease-renewal-interval-in-seconds: 5
    # 租约到期时间(默认90秒),如下所示,告诉服务端如果我 10s 之内没有给你发心跳,就代表我"死"了,将我踢出掉
    lease-expiration-duration-in-seconds: 10

可以参考官网介绍:Why Is It so Slow to Register a Service?