官方解释: 自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。
默认情况下,Eureka Client
会定时的向 Eureka Server
端发送心跳包,默认是30s
发送一次,目的是告诉 Eureka Server
当前客户端实例还处于存活状态,如果Eureka server
在一定时间内没有收到实例的心跳,便会把该实例从注册表中删除(默认是90
秒),但是,如果短时间内丢失大量的实例心跳,便会触发Eureka server
的自我保护机制的 ,默认自我保护机制处于开启状态,比如在开发测试时,需要频繁地重启微服务实例客户端,但是我们很少会把eureka server一起重启(因为在开发过程中不会修改eureka注册中心),当一分钟内收到的心跳数大量减少时,会触发该保护机制。可以在eureka管理界面看到Renews threshold
和Renews(last min)
,当Renews(last min)
(最后一分钟收到的心跳数)小于Renews threshold
(心跳阈值)的时候,如果某个服务实例宕机掉,触发保护机制,会出现红色的警告:
因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个 Eureka 节点会退出"自我保护模式"。
当一个服务未按时进行心跳续约时,在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。
为了防止在一定时间内,Eureka Client
与Eureka Server
在网络不同的情况下,Eureka Server误将Eureka Client服务剔除,这个机制是为了对服务进行保护;
Eureka自我保护机制默认是开启的,如果如果需要关闭自我保护机制,按照下述方式: enable-self-preservation: false
开关关闭掉,然后修改客户端和服务端相关参数,保证异常服务能及时剔除;
注册中心关闭自我保护机制,修改检查失效服务的时间,以确保注册中心将不可用的实例及时正确剔除
yml:
#Eureka自我保护机制
server:
#关闭eureka自我保护机制false(默认为true)
enable-self-preservation: false
# 配置Eureka Server清理无效节点的时间间隔(单位毫秒,默认60*1000毫秒,即60秒)
eviction-interval-timer-in-ms: 2000
#关闭自我保护:true 为开启自我保护,false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(单位:毫秒,默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=2000
然后启动server和服务,观察关闭服务前后的变化
减短客户端服务发送服务心跳给服务端的时间, 在开发测试时,将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
eureka:
instance:
#eureka服务端在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此删除,单位为秒(默认为90s),超过时间则剔除(客户端会按照此规则向Eureka服务端发送心跳检测包)
lease-expiration-duration-in-seconds: 90
#eureka客户端需要多长时间发送心跳给eureka服务端,单位为秒(默认为30s),(客户端会按照此规则向Eureka服务端发送心跳检测包)
lease-renewal-interval-in-seconds: 2
获取服务列表
当服务消费者启动是,会检测eureka.client.fetch-registry=true
参数的值,如果为true,则会从Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒
会重新获取并更新数据。我们可以通过下面的参数来修改:
eureka:
client:
#表示eureka client间隔多久去拉取服务器注册信息,默认为30秒
registry-fetch-interval-seconds: 5
生产环境中,我们不需要修改这个值。
但是为了开发环境下,能够快速得到服务的最新状态,我们可以将其设置小一点。
当我们在使用微服务框架做项目开发的时候,如果注册中心是Eureka
,因为会频繁的重启本地开发环境,调试和修改代码,但是不会频繁的重启Eureka Server
,所以建议在测试环境、本地开发环境时关闭Eureka的自我保护机制,,如果触发了保护机制,则旧的服务实例没有被删除,这时请求有可能跑到旧的实例中,而该实例已经关闭了,这就导致请求错误,影响开发测试效率;
Linux—>Docker容器化部署—>K8S
在微服务各个节点部署到生产环境了之后,建议开启Eureka自我保护环境,这一点还是比较重要的,因为在生产环境,并不会频繁的重启,而且有时在短时间内可能会发生服务与服务之间网络故障、重启Eureka Client
客户端服务实例等其他原因导致通讯中断,所以一定要把自我保护机制打开,否则网络一旦终端,就无法恢复,导致误删除服务节点,造成生产故障;
希望大家关注我一波,防止以后迷路,有需要的可以加我Q讨论互相学习java ,学习路线探讨,经验分享与java Q:2415773436