前言:在上一章节中我们说明了一些关于Eureka的服务发现功能,也用这个功能进行接口的实现,在本章节则介绍一些关于Eureka的自我保护
1、Eureka保护模式概述
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。默认情况下Eureka Client会定时向Eureka Server端发送心跳包,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)将该服务从服务注册列表中剔除,但是如果在短时间(90秒)内丢失了大量的服务实例心跳,这时候Eureka Server就会开启自我保护模式(短时间内丢失大量心跳包可能是因为网络不通的原因,这时候Eureka Client是正常运行的,过一会可能网络就恢复了,服务就恢复正常了,但如果因为网络问题没收到心跳包就把服务剔除,这就很冤了,造成严重失误了,所以为了解决这种问题,Eureka提出了保护模块的概念)一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,就是不会注销任何服务实例;简单来说就是某时刻某一个微服务因为网络故障或者其他原因导致不可用了,在一定的时间内Eureka没有收到微服务的心跳反应,但是Eureka不会立刻清理,依旧会对该微服务的信息进行保存,等微服务恢复,这是一种高可用的设计思想(Eureka的保护模式这种高可用设计思想属于CAP理论里面的AP架构)
有兴趣的同学可以简单的了解下CAP理论:
https://blog.csdn.net/m0_64284147/article/details/132258051
综上,自我保护模式是一种应对网络异常的安全保护措施,它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务,使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
2、Eureka进入保护模式的特征
如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式
3、关闭Eureka的自我保护模式
如果想关闭Eureka的自我保护模式,这时候就可以通过修改配置来实现
(1)分别修改eureka-server7001和eureka-server7002的application.yml文件在eureka参数下加上server:enable-self-preservation: false这一参数,从而关闭Eureka的自我保护模式
例:
eureka-server7001
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7001.com
client:
#false表示不向服务中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,只需要维护服务实例,并不需要检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka/
server:
#关闭自我保护模式,不可用服务会被及时被删除
enable-self-preservation: false
eureka-server7002
server:
port: 7002
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7002.com
client:
#false表示不向服务中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,只需要维护服务实例,并不需要检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/
server:
#关闭自我保护模式,不可用服务会被及时被删除
enable-self-preservation: false
(2)关闭Eureka的自我保护模式后为了更快的体验到Eureka自我保护模式的关闭,我们在这里也要修改Eureka Server的清理失效服务的时间间隔,修改Eureka Client向Eureka Server发送心跳的时间间隔和让Eureka Server收到最后一次心跳后等待的时间上限
例:
eureka-server7001
server:
port: 7001
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7001.com
client:
#false表示不向服务中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,只需要维护服务实例,并不需要检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka/
server:
#关闭自我保护模式,不可用服务会被及时被删除
enable-self-preservation: false
#Eureka服务端清理失效服务的时间间隔(默认是90秒)
eviction-interval-timer-in-ms: 2000
eureka-server7002
server:
port: 7002
eureka:
instance:
#eureka服务端的实例名称
hostname: eureka7002.com
client:
#false表示不向服务中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,只需要维护服务实例,并不需要检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/
server:
#关闭自我保护模式,不可用服务会被及时被删除
enable-self-preservation: false
#Eureka服务端清理失效服务的时间间隔(默认是90秒)
eviction-interval-timer-in-ms: 2000
provider-payment8001
#服务端口号
server:
port: 8001
#服务名称
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包(mysql驱动包版本是5的要写成com.mysql.jdbc.Driver)
url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 #mysql连接路径,记得把cloud这个数据库名改成自己的,或者新建名为cloud的数据库
username: root
password: 123456
eureka:
client:
#表示是否将自己注册进Eureka Server里,默认为true
register-with-eureka: true
#是否从Eureka Server抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
instance-id: payment8001
#访问路径可以显示IP地址
prefer-ip-address: true
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
#mybatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml #扫描类路径下的mapper文件夹下所有的.xml配置文件
type-aliases-package: com.ken.springcloud.entities #该包下的所有Entity类都取默认别名
provider-payment8002
#服务端口号
server:
port: 8002
#服务名称
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包(mysql驱动包版本是5的要写成com.mysql.jdbc.Driver)
url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 #mysql连接路径,记得把cloud这个数据库名改成自己的,或者新建名为cloud的数据库
username: root
password: 123456
eureka:
client:
#表示是否将自己注册进Eureka Server里,默认为true
register-with-eureka: true
#是否从Eureka Server抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
instance-id: payment8002
#访问路径可以显示IP地址
prefer-ip-address: true
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
#mybatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml #扫描类路径下的mapper文件夹下所有的.xml配置文件
type-aliases-package: com.ken.springcloud.entities #该包下的所有Entity类都取默认别名
(3)查看配置是否生效
重新启动eureka-server7001模块和eureka-server7002模块,最后再启动provider-payment8001模块和provider-payment8002模块,然后分别进入http://eureka7001.com:7001/和http://eureka7002.com:7002/查看效果,可以发现页面上的红色提示变成了THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.,这说明Eureka的自我保护模式已经关闭了,然后我们也能看到provider-payment8001模块和provider-payment8001模块已经成功注册进Eureka Server里了
(4)停掉两个服务提供者provider-payment8001模块和provider-payment8002模块,然后回到Eureka Server的页面刷新,查看Eureka Server在关闭自我保护模式的情况下对待Eureka Client的情况
可以看到当provider-payment8001模块和provider-payment8002模块停掉后,Eureka Server马上就把provider-payment8001模块和provider-payment8002模块这两个服务剔除了,而不是继续保留,这也进一步验证Eureka的自我保护模式已经关闭
注意:如果想对比Eureka自我保护模式关闭前后的区别,停服务时最好不要在IDEA等工具里面停,最好是用任务管理器关闭服务,因为IDEA关停服务后服务会通知Eureka Server下线了,这样Eureka Server也会立马剔除服务,导致看不出关停自我保护模式前后的区别