Eureka 自我保护模式、健康检查机制、Eureka 元数据

目录

Eureka 自我保护模式

健康检查机制

Eureka 元数据


声明:本文使用的 Spring Cloud 版本为 "Greenwich.RELEASE",对应的 Spring Cloud Netflix Eureka 版本为 2.1.0


Eureka 自我保护模式

官方关于 Eureka 自我保护的解释:Understanding Eureka Peer to Peer Communication

提取总结一句:Eureka Server 自我保护模式在实际生产环境中,建议直接默认开启即可,不推荐进行关闭。本文的目的旨在更好的理解自我保护模式,以及在平时测试练习的时候可以对其进行关闭。

1、什么是 Eureka Server  自我保护?

1)自我保护工作机制:如果 Eureka Server 在 15 分钟内有超过 85% 的 Eureka Client 都没有正常的发送心跳过来(单机模式时尤为明显),那么 Eureka Server 就认为注册中心与客户端出现了网络故障,Eureka Server 自动进入自我保护机制。

2)这也就是为什么平时使用一个 Eureka Server 与一个 Eureka Client 时,即使手动关闭了 Eureka Client,但是 Eureka Server 主页中“Instances currently registered with Eureka”下面 status 栏仍然显示为 UP。

3)进入自我保护模式后,Eureka Server 的 Spring Eureka 主页会出现如下红色提示信息

#转为小写看起来更直观
emergency! eureka may be incorrectly claiming instances are up when they're not. 
renewals are lesser than threshold and hence the instances are not being expired just to be safe.
#翻译
紧急情况!Eureka可能错误地声称实例已经启动,而事实并非如此,续约低于阈值,为了安全起见实例不会过期

4、自我保护的原则是:宁可放过,不可杀错!自我保护模式是一种针对网络异常波动的安全保护措施,能使 Eureka 集群更加的健壮、稳定的运行。

2、为什么引入 Eureka Server 自我保护?

1)正常情况(15 分钟内没有超过 85% 的 Eureka Client 都没有正常的发送心跳)下,如果 Eureka Server 在约定时间内(默认90秒)没有接收到某个微服务(Eureka Client)实例的心跳,Eureka Server 将会移除该实例。

2)但当网络分区故障发生时,大面积(甚至所有)微服务(Eureka Client)都与 Eureka Server 之间无法正常通信,而各个微服务本身是能正常运行的,此时注册中心不应该移除这些微服务,所以引入了自我保护机制。

3、Eureka Server  自我保护后会怎么样?

1)Eureka Server 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务(Eureka Client)

2)Eureka Server 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它 Eureake Server 上,保证当前节点依然可用。

3)当网络稳定/恢复后,Eureka Server节点会自动退出自我保护模式,期间新的注册信息会被同步到其它 Eureake Server  节点中。

4、如何开启与关闭自我保护?

1)Eureka Server 自我保护模式默认已经开启,如果需要关闭,则在 Eureka Server 端的全局配置文件可以使用如下属性:

#配置 Eureka Server
eureka:server:enable-self-preservation: false #关闭自我保护机制,实际生产环境时建议不要关闭eviction-interval-timer-in-ms: 5000 #驱逐计时器扫描失效服务的间隔时间(默认为60*1000ms),纯粹为了演示才写上,建议不覆盖使用默认值

 

THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
#转为小写看起来更直观
the self preservation mode is turned off. this may not protect instance expiry in case of network/other problems.
#翻译
自我保护模式已关闭,如果出现网络/其他问题,这可能无法保护实例过期。

3)eureka.server.eviction-interval-timer-in-ms=5000 修改驱逐计时器扫描失效服务间隔时间后,运行日志可以看到现在每隔 5 秒 EvictionTimer 就会执行一次(以前默认是1分钟才执行一次)。

4)eureka.server.eviction-interval-timer-in-ms 不建议修改,因为即使即使修改了,哪怕是 每隔 1s 执行一次,当手动关闭 Eureka Client 后,注册中心也并不会立马注销此节点,同样要等到约 90 秒左右收不到客户端心跳才会将其移除。

...
2019-03-15 11:54:57.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:02.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:07.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:12.312  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:17.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:22.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2019-03-15 11:55:27.313  INFO 2224 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
...

5、如何修改 Eureka Client 心跳发送间隔时间?

1、作为一个实例,需要定期向注册表发送心跳(通过客户端的 serviceurl),默认间隔时间为 30秒。在实例、服务器和客户机的本地缓存中都具有相同的元数据,因此默认 90 秒内需要至少3次心跳,否则服务器会警告:RENEWALS ARE LESSER THAN THE THRESHOLD(更新低于阈值)

2)如上所示 Renews threshold 为 3,表示默认 90 秒内应该至少收到 3 次心跳,如果低于此值,则会警告:renewals are lesser than the threshold(更新低于阈值)

3)可以在 Eureka Client 端通过设置 eureka.instance.leaseRenewalIntervalinSeconds 属性来更改心跳发送时间,将其设置为小于 30 的值可以加快将客户机连接到其他服务的过程,在生产环境中,最好还是坚持使用默认值,因为服务器中的内部计算会对租约续订期进行假设。

#配置 Eureka Client
eureka:client:serviceUrl:defaultZone: http://admin:123456@192.168.1.20:8761/eurekaServer_shenZhen/eureka #账号密码必须和服务端提供的一致,ip必须指向服务端instance:# 租约续订间隔时间(默认30秒),如下所示每间隔 5s 向服务端发送一次心跳,证明自己依然"存活"lease-renewal-interval-in-seconds: 5# 租约到期时间(默认90秒),如下所示,告诉服务端如果我 10s 之内没有给你发心跳,就代表我"死"了,将我踢出掉lease-expiration-duration-in-seconds: 10

可以参考官网介绍:Why Is It so Slow to Register a Service?

健康检查机制

1、Eureka Server 与 Eureka Client 之间使用心跳机制来确定 Eureka Client 的状态,默认情况下,服务器端与客户端的心跳保持正常,应用程序就会始终保持"UP"状态,所以微服务的 UP 并不能完全反应应用程序的状态。

2、spring-boot-actuator 组件的功能就是进行监控和管理应用程序,它提供了很多的访问端点,但是默认只启用的 /info、/health ,默认前缀为 /actuator。

3、info 端点默认是启用的,并且是公开的,当浏览器访问 http://ip:port/context-path/actuator/info 时,是可以访问到的,但是默认不会显示任何内容。可以在全局配置文件中自定义 info.* 属性,由 info 端点向外进行公开数据。info key 下的所有环境属性都将自动对外公开。

#项目配置说明,"@xxx@" 动态获取的全局文件中对应标签的值
info:app:name: @project.artifactId@encoding: @project.build.sourceEncoding@source: @java.version@target: @java.version@token: 8868ui5435ft656gh

4、本文环境:Java JDK 1.8 + Spring Boot 2.1.3 + Spring Cloud Greenwich.SR1。使用非常简单,两步到位:

1)Eureka Server 注册中心与 Eureka Client 客户端都需要引入 spring-boot-starter-actuator 依赖(注:spring-cloud-starter-netflix-eureka-server 组件默认已经依赖了 actutor,所以服务端不需要再导入)。

2)可以访问地址:http://Eureka Client ip:Eureka Client port/context-path/actuator/health、http://Eureka Client ip:Eureka Client port/context-path/actuator/info

Eureka Client ip:客户端 ip、Eureka Client port:客户端端口、context-path:客户端应用上下文、actuator/health 与 actuator/info 写死

Eureka 元数据

1、官网传送:Eureka Metadata for Instances and Clients。

2、可以使用 eureka.instance.metadataMap 配置元数据,远程客户端中可以访问此元数据。附加元数据不会更改客户端的行为,除非客户端使用已知的元数据名称(如 zone),因为 Spring Cloud 已经为这些特定名称的元数据映射指定了含义。

3、在 Eureka 客户端配置文件中配置 eureka.instance.metadataMap 元素据:

eureka:client:service-url:defaultZone: http://localhost:9393/eureka/ #eureka 服务器地址instance:prefer-ip-address: true # IP 地址代替主机名注册instance-id: changSha-food # 微服务实例id名称metadata-map: #定义元数据,key-value 自定义即可zone: chinawmx: cool

4、启动之后,可以访问 Eureka 注册中心,如:http://localhost:9393/eureka/apps/EUREKA-CLIENT-FOOD,最后的 "EUREKA-CLIENT-FOOD" 为注册的 Eureka 客户端服务名称。可以在其中的 标签中看到客户端定义的元素据。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平