Eureka自我保护机制
我们在使用Eureka的时候(尤其是做实验测试的时候)经常会看到Eureka界面冒出来这样一段红色的警示语句
中文翻译如下:
紧急情况!尤里卡可能不正确地声称实例在不在的情况下出现。续订小于阈值,因此不会为了安全而过期实例。
出现这种情况的解释说明是:当前Eureka进入了自我保护模式
其中官方解释是这样的:
自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。
那很好奇的是怎么才能进入到这个状态呢,众所周知的Eureka注册中心最主要的作用就是将我们一个个的微服务集中话管理供别人调用,我们在将服务注册到我们的注册中心的时候,Eureka Client会向Eureka Server(服务中心)发送第一次心跳,会将服务的实例信息注册到注册中心
Eureka Client 每30秒来发送一次心跳来更新实例信息。通知Eureka Server该实例仍然存在(也就是该能正常的提供服务)。如果超过90秒没有发送更新(有可能是服务关闭或者网络异常情况),则服务器将从注册信息中将此服务移除。
关键是最后一句话:
如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例
牛顿说过:没有人能保证网络一直能ping的通,所以问题产生了:
- 微服务能正常运行
- 微服务与Eureka Server之间无法正常通信(心跳不通)
上述的条件1和条件2就构成了一个悖论,现实是不应该在Eureka注册中心删除这一个能够正常工作的微服务
这个情况下Eureka为了防止误杀情况产生,就自己进入了自我保护机制
定义:
如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制
在进入这个自我保护机制的时候我们来看一下我们Eureka头部的System Status的描述是这样的:
重点看红色区域位置的三个参数(测试的时候其实只启用了一台Eureka注册中心,一个服务实例Eureka Client也没有…)
- Lease expiration enabled //租约到期已启用
- Renews threshold //更新阈值
- Renews (last min) //更新(最后一分)
Lease expiration enabled的含义是是否启用租约过期 ,当期关闭时该值默认是true, 自我保护机制开启之后为false
如果心跳失败比例在 15 分钟之内低于 85% 这个时候就会触发 Eureka 的保护机制,但是开启了保护机制,则服务注册中心维护的服务实例就不是那么准确了,此时我们可以使用eureka.server.enable-self-preservation=false来关闭保护机制,这样可以确保注册中心中不可用的实例被及时的剔除。
eureka:
server:
enable-self-preservation: false //关闭自我保护机制
重启我们Eureka服务,我们会在页面上看到:
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT
INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
翻译为:
自动保存模式关闭。这可能无法在出现网络/其他问题时保护实例到期。
可以看到官方都不是很推荐这种情况的发生
刚才我们在规则中看到两个非常重要的时间30s和90s,他们的含义是
Eureka Client 每30秒来发送一次心跳来更新实例信息。通知Eureka Server该实例仍然存在(也就是该能正常的提供服务)。如果超过90秒没有发送更新(有可能是服务关闭或者网络异常情况),则服务器将从注册信息中将此服务移除。
也就是说美国30s服务提供者需要向Eureka注册中心通知一声:我能正常使用,但是如果90S内没有发送这种能正常使用的同坐,那么Eureka注册中心就会认为你出了问题,当然这两个时间也是可以在代码中手工调整的,如下:
eureka:
server:
enable-self-preservation: false
instance:
hostname: localhost # Eureka注册服务器名称
lease-expiration-duration-in-seconds: 10 #默认90秒
lease-renewal-interval-in-seconds: 10 #默认30秒
最后强调:以上所有设置,最好都是用默认值