Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。

我们在单机测试的时候很容易满足心跳失败比例在 15 分钟之内低于 85%,这个时候就会触发 Eureka 的保护机制,一旦开启了保护机制,则服务注册中心维护的服务实例就不是那么准确了,此时我们可以使用eureka.server.enable-self-preservation=false来关闭保护机制,这样可以确保注册中心中不可用的实例被及时的剔除(不推荐)。

自我保护模式被激活的条件是:在 1 分钟后,Renews (last min) < Renews threshold

这两个参数的意思:

  • Renews thresholdEureka Server 期望每分钟收到客户端实例续约的总数
  • Renews (last min)Eureka Server 最后 1 分钟收到客户端实例续约的总数

具体的值,我们可以在 Eureka Server 界面可以看到:

可以看到,我们部署了 3 个 Eureka Server(自注册模式),另外,又部署 7 个服务,注册到 Eureka Server 集群,参数值分别为:

  • Renews threshold:17
  • Renews (last min):20

下面说下Renews thresholdRenews threshold具体计算方式。

Renews threshold 计算代码:

this.expectedNumberOfRenewsPerMin = count * 2;
this.numberOfRenewsPerMinThreshold = (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());

count表示服务的数量,如果 Eureka Server 开启自注册模式,也算一个服务,比如我们上面的示例,count的值就是 10(3 个自注册服务 + 7 个独立服务),serverConfig.getRenewalPercentThreshold()默认是 0.85(可以通过eureka.server.renewal-percent-threshold配置)。

所以,根据上面的分析,我们可以计算出Renews threshold的值:(int)(10 * 2 * 0.85) = (int)17 = 17

Renews (last min)计算方式:count * 2,数值 2 表示每 30 秒 1 个心跳,每分钟 2 个心跳的固定频率因子,所以具体值为:10 * 2 = 20

如果在 1 分钟后,Renews (last min) < Renews threshold,默认需等待 5 分钟(可以通过eureka.server.wait-time-in-ms-when-sync-empty配置),即 5 分钟后你会看到下面的提示信息:

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.server.enable-self-preservation设为false),不推荐
  • 降低renewalPercentThreshold的比例(eureka.server.renewal-percent-threshold设置为0.5以下,比如0.49),不推荐
  • 部署多个 Eureka Server 并开启其客户端行为(eureka.client.register-with-eureka不要设为false,默认为true),推荐

Eureka 的自我保护模式是有意义的,该模式被激活后,它不会从注册列表中剔除因长时间没收到心跳导致租期过期的服务,而是等待修复,直到心跳恢复正常之后,它自动退出自我保护模式。这种模式旨在避免因网络分区故障导致服务不可用的问题。例如,两个客户端实例 C1 和 C2 的连通性是良好的,但是由于网络故障,C2 未能及时向 Eureka 发送心跳续约,这时候 Eureka 不能简单的将 C2 从注册表中剔除。因为如果剔除了,C1 就无法从 Eureka 服务器中获取 C2 注册的服务,但是这时候 C2 服务是可用的。

所以,Eureka 的自我保护模式最好还是开启它。


Eureka Server 单机版配置示例:

debug: true
spring:
application:
name: eureka-server
logging:
level:
com.netflix.eureka: 'off'
com.netflix.discovery: 'off'
server:
port: 8100
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: false #关闭自我保护机制
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

参考资料:

Spring Cloud Eureka 自我保护机制的更多相关文章

  1. Spring Cloud Eureka 自我保护机制实战分析

    前些天栈长在Java技术栈微信公众号分享过 Spring Cloud Eureka 的系列文章: Spring Cloud Eureka 自我保护机制 Spring Cloud Eureka 常用配置 ...

  2. Spring Cloud Eureka自我保护机制

    自我保护背景 首先对Eureka注册中心需要了解的是Eureka各个节点都是平等的,没有ZK中角色的概念, 即使N-1个节点挂掉也不会影响其他节点的正常运行. 默认情况下,如果Eureka Serve ...

  3. Spring Cloud Eureka自我保护机制(服务无法剔除)

    说明 自我保护背景 首先对Eureka注册中心需要了解的是Eureka各个节点都是平等的,没有ZK中角色的概念, 即使N-1个节点挂掉也不会影响其他节点的正常运行. 默认情况下,如果Eureka Se ...

  4. spring cloud 的自我保护机制

    spring cloud 的自我保护机制定义: 自我保护模式是:在出现网络异常波动的情况下,使用自我保护模式使eureka 集群更加健壮,稳定. 自我保护机制是:在15分钟内客户端没有雨注册中心发生心 ...

  5. Spring Cloud Eureka 常用配置详解,建议收藏!

    前几天,栈长分享了 <Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!>,今天来分享下 Spring Cloud Eureka 常用的一些参数配置及说 ...

  6. Spring Cloud Eureka 你还在让它裸奔吗??

    前些天栈长在微信公众号Java技术栈分享了 Spring Cloud Eureka 最新版 实现注册中心的实战教程:Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版 ...

  7. Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!

    Spring Cloud 的注册中心可以由 Eureka.Consul.Zookeeper.ETCD 等来实现,这里推荐使用 Spring Cloud Eureka 来实现注册中心,它基于 Netfl ...

  8. Spring Cloud Eureka 注册安全一定要做到位!

    /eureka/ 参考配置如下: defaultZone: http://javastack:javastack@eureka1:8761/eureka/, http://javastack:java ...

  9. Spring Cloud Eureka集群配置及注意事项(Greenwich版本)

    Spring Cloud Eureka集群配置及注意事项(Greenwich版本) 一·概述 Spring Cloud Netflix Eureka 是一个提供服务注册与发现的套件.服务提供者只需要将 ...

随机推荐

  1. 云计算--网络原理与应用--20171120--VLAN与三层交换机配置

    什么是VLAN及其配置 Trunk的原理与配置 三层交换机的基本配置 实验:配置一个三层交换机 一 VLAN 的概念及优势 VLAN(virtual local area network)就是虚拟局域 ...

  2. beta冲刺4

    昨天的问题: 我的社团数据库表项的处理,代码修改后结果无法显示. 帖子内容无法显示出来. 首页图像未替换 登陆整合没有完成 今天的完成: 服务器部署成功 页面背景修改.(已上传,未确认实装.) 任务截 ...

  3. Beta Scrum Day 1

    听说

  4. Beta敏捷冲刺每日报告——Day1

    1.情况简述 Beta阶段Scrum Meeting 敏捷开发起止时间 2017.11.2 00:00 -- 2017.11.3 00:00 讨论时间地点 2017.11.2 晚9:30,电话会议会议 ...

  5. Jmeter读取文件中的值《一》

    此篇主要是对应上一章节的呼应,上一篇中讲到将返回值写入文件,这个值如果在下一个接口中用到, 那么我们需要去从文件中读取数据,这是我们该如何操作? 一.测试计划中添加CSV Data Set Confi ...

  6. 码农、黑客和2B程序员之间的区别

    码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L<<32 ...

  7. C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现

    我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...

  8. c 语言typedef 和 define的使用和区别

    #define是C的指令,用于为各种数据类型定义别名,与typedef 类似,但是有一下几点不同 1,typedef仅限于为类型定义符号名称,而#define不仅可以为类型定义符号名称,也能为数值定义 ...

  9. ( 转 ) 聊一聊C#的Equals()和GetHashCode()方法

    聊一聊C#的Equals()和GetHashCode()方法   博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. ...

  10. Spring源码阅读-spring启动

    web.xml web.xml中的spring容器配置 <listener> <listener-class>org.springframework.web.context.C ...