首页 资讯 社群 我的社区 搜索

SPRINGCLOUD项目之EUREKA自我保护模式

LM123
2019-07-18 17:52:38

默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。

Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。

综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保护模式。

 

进入自我保护的直观表现如下:

官方说明如下:

当一个Eureka server 启动,它将尝试从一个相邻节点中获取所有的注册信息,
如果从一个邻接点中获取信息出现问题,此server会尝试从其他节点获取,直到所有节点都失败。
如果这个服务成功的从其他节点中获取到了注册信息,它将基于这些信息设置一个刷新阈值(心跳阈值)。
如果某个时刻,心跳数低于这个阈值的一个百分比,这个服务将停止移除instance,从而保护当前已经注册过的instance的信息,即进入self-preservation模式。
 
自我保护具体逻辑如下:
  1. 假定有两个client注册到Eureka server,每个client每30s发送一次心跳,则server需要一分钟收到4次心跳。spring 在此基础上追加了一个最小心跳值1(通过eureka.instance.registry.expectedNumberOfRenewsPerMin设置),如此一来,最小的心跳数变成了5,然后这个值还需要乘以最小阈值百分比0.85(eureka.server.renewalPercentThreshold),并近似为比本身大的最小整数 5*0.85=4.25 -->5。此阈值每15分钟才会更新一次(通过eureka.server.renewalThresholdUpdateIntervalMs设置),因此在这15分钟内的任何时间点server收到的心跳数低于5次,这个server就进入self-preservation模式,并停止移除instance信息。 
  2. Eureka server假定每一个client都是以每30s一次的固定频率发送心跳。如果注册了两个client,server就期望一分钟收到(2+2+1)*0.85=5 次心跳,如果收到的次数比这个值小,就会激活self-preservation模式。假定现在每一个client发送心跳都加快(10s一次),server在一分钟内就会收到12次,即便有一个服务down掉,还能收到6次,仍然大于期望的5次,如此就不会触发原本应该触发的self-preservation模式,这也是为什么官方不建议修改eureka.instance.leaseRenewalIntervalInSeconds值。 
用户评论