昨天生产突然出了问题,调用方反馈我们这边的服务调不通。
查看日志发现,有个应用节点假死了,超过了十分钟。
项目使用的是 springboot 框架,Eureka 做应用管理。
默认情况下,应用服务(Eureka Client)会每隔30秒向 Eureka(Eureka Server) 发送一次心跳检测,超过90秒 Eureka Server 收不到心跳就认为服务挂了,就会将此服务节点从服务清单中删除。
但是,但是,但是,Eureka Server 默认还会开启自我保护机制。
当网络故障发生(延时、卡顿、拥挤)时,微服务与 Eureka Server之间无法正常通信,以上行为就变得非常危险,因为微服务本身其实是健康的,此时不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题,当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server 会保护服务注册表中的信息,不再注销任何服务实例。
它的设计哲学就是并可保留错误的服务注册信息,也不可能盲目注销任何可能健康的服务实例。
关闭Eureka自我保护机制
Eureka Server 增加配置参数
#关闭自我保护机制,保证不可用服务被及时踢除
eureka.server.enable-self-preservation=false
# 清理间隔(单位毫秒,默认是60*1000)
eureka.server.eviction-interval-timer-in-ms=2000
Eureka Client 增加配置参数
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
eureka.instance.lease-renewal-interval-in-seconds=1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
eureka.instance.lease-expiration-duration-in-seconds=2
然后分别重启 Eureka Server 和 Eureka Client,使配置生效,等应用再次失效时,就会被 Eureka Server 立刻清理掉了。