Version: Next
Eureka 自我保护
概述
- 保护模式主要用于一组
客户端
与Eureka Server
之间存在网络分区
场景下的保护- 一旦进入
保护模式
,Eureka Server
将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,即 不会注销任何微服务- 如果在
Eureka Server
也面看到以下提示,则说明Eureka
进入了保护模式
- 即:某时刻某个微服务不可用了,Eureka 不会立刻将其清理,依旧会对该微服务的信息进行保存,属于
CAP
中的AP
分支 (先不管啥意思)
为什么会产生 Eureka 自我保护
- 为了防止
Eureka Client
可以正常运行,但是Eureka Server
网络不通畅的情况- 在这种情况下,我们希望
Eureka Server
不会立刻将Eureka Client
服务提出,因为其并不是真的停止了,只是暂时失联
什么是自我保护模式
- 默认情况下,
Eureka Server
与微服务实例
之间维持心跳 - 超过一定时间
Eureka Server
没有接收到微服务实例
心跳,则将其实例注销(默认90
秒) - 但当网络发生故障(如
延时
、卡顿
、拥挤
)时,微服务
与Eureka Server
之间无法正常通信,则以上机制存在弊端微服务实例
本身是健康的,此时 不应该将其注销
Eureka
通过 自我保护模式 来解决这个问题:- 当
Eureka Server
节点在短时间内丢失过多客户端时,那么此Eureka Server
节点就会进入自我保护模式
- 当
《Spring cloud 与 Docker 微服务框架实战》
禁止Eureka自我保护
一旦微服务掉线,注册中心等待一端时间后将其删除
Eureka-Server7001
eureka-server-7001
:- 关闭自我保护:修改 YAML 文件,设置
eureka.server.enable-self-preservation=false
- 修改心跳等待时间:设置
eureka.server.evication-interval-timer-in-ms=2000
,失联 2000 毫秒就干掉- 恢复到
单机模式
方便测试server:port: 7001eureka:instance:# hostname: localhost #eureka服务端的实例名称hostname: eureka7001.com # 集群环境下,在hosts文件配置了自己地址的名字client:# false表示不向注册中心注册自己register-with-eureka: false# false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要检索服务fetch-registry: falseservice-url:# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址# 单机defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# 集群:使用定义在 hosts 里的名称,注册到对方节点# defaultZone: http://eureka7002.com:7002/eureka/server:enable-self-preservation: false # 关闭 Eureka 自我保护eviction-interval-timer-in-ms: 2000 # 失联 2 秒就把微服务干掉
- 启动
7001
,访问localhost:7001
自我保护模式已关闭。这可能导致在网络或其他故障时不能保护(微服务)实例
provider-payment8001
provider-payment8001
eureka.instance.lease-renewal-interval-in-seconds=30
:Eureka 客户端向服务端发送心跳信号的时间间隔,默认为 30 秒,重新设置为1
eureka.instance.lease-expiration-duration-in-seconds=90
:Eureka 服务端在受到最后一次心跳后等待的时间上限,默认为 90 秒,超时则注册中心将微服务剔除,重新设置为2
- 恢复到
单机模式
server:port: 8081spring:application:name: cloud-payment-servicedatasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/springcloud?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcemybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:map-underscore-to-camel-case: true #驼峰映射log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #调试打印SQLeureka:client:#表示是否将自己注册进EurekaServer默认为trueregister-with-eureka: true#是否从EurekaServer抓取已有的注册消息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡fetch-registry: trueservice-url:#集群版#defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/#单机版 入驻到这个地址(就是注册中心地址)defaultZone: http://127.0.0.1:7001/eureka/instance: # 用来修改服务名称,防止暴露当前服务器主机instance-id: payment8001prefer-ip-address: true # 可以预览 ip 地址lease-renewal-interval-in-seconds: 1 # Eureka 客户端向服务端发送心跳信号的时间间隔lease-expiration-duration-in-seconds: 2 # Eureka 服务端在受到最后一次心跳后等待的时间上线
测试
- 使用
Debug
启动7001
和8001
可以看到注册中心中已经注册了8001
微服务
- 故意关闭
8001
项目,可以看到注册中心立刻剔除8001
微服务