之前我说明了Eureka注册中心的保护模式,由于在该模式下不能剔除失效节点,故按原有配置在实际中不剔除总感觉不是太好,所以深入研究了一下。当然,这里重申一下,不管实例是否有效剔除,消费端实现Ribbon重试机制也是必须的。

说下背景,在微服务架构中,有个CAP原则(一致性,可用性,分区容错性),三者由于存在互斥,只能同时满足其二,第三点需要有一定舍弃。Eureka舍弃了强一致性,所以在进入保护模式后,失效节点的一致性不能得到保证。

以下是我验证后的几种方式,可以实现服务的及时剔除。

1、关闭自我保护模式eureka.server.enable-self-preservation=false来关闭。但是,这种方式有违eureka的CAP原则,所以,我并不推荐这种方式。

2、在说明之前,我们先看下源码。

以下代码判断是否进入刷新服务列表的步骤。该代码在AbstractInstanceRegistry.java和PeerAwareInstanceRegistryImpl.java中。

public void evict(long additionalLeaseMs) {
logger.debug("Running the evict task");
//主要是看isLeaseExpirationEnabled返回值
if (!isLeaseExpirationEnabled()) {
logger.debug("DS: lease expiration is currently disabled.");
return;
}
//进入筛选过期实例的方法。这里省略
}
public boolean isLeaseExpirationEnabled() {
//isSelfPreservationModeEnabled由是否开启保护模式配置决定,默认为true
if (!isSelfPreservationModeEnabled()) {
return true;
}
return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold;
}

主要看numberOfRenewsPerMinThreshold和getNumOfRenewsInLastMin()方法。我们主要看numberOfRenewsPerMinThreshold初始化的地方。getNumOfRenewsInLastMin()方法是统计最后一分钟内的心跳统计总数。

//PeerAwareInstanceRegistryImpl.java
public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
// Renewals happen every 30 seconds and for a minute it should be a factor of 2.
this.expectedNumberOfRenewsPerMin = count * 2;
this.numberOfRenewsPerMinThreshold =
(int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
//....
}

count是注册在注册中心的实例总数,包括高可用的另外注册中心。我们可以看到,这里是以硬编码的方式初始化expectedNumberOfRenewsPerMin,通过 实例数*2。为什么*2,因为实例默认发送心跳时间是30s,所以通过*2统计一分钟类应收到的总的心跳次数,因为是硬编码,所以不建议修改实例端心跳周期时间!。numberOfRenewsPerMinThreshold是通过总的心跳数乘以允许失败的比例。默认为0.85。expectedNumberOfRenewsPerMin在默认情况下,会每隔15分钟刷新一次。

通过上面分析,我们大致了解了不通过关闭自我保护模式下触发服务剔除操作的条件。得出以下两种方案来实现失效节点的剔除(亲测有效)。

  1. 通过修改每分钟心跳成功最低比例来控制注册中心不进入自我保护模式,实时剔除节点(需要等到实例定义的过期时间,且注册中心触发刷新周期)。eureka.server.renewal-percent-threshold来配置比例。举个例子,当前我们有4个服务实例,计算所知,每分钟有4*2=8个心跳,当需要实现一个实例意外掉线后,则每分钟实际收到心跳为6个,8*x<6时不会进入保护模式,则x<0.75,配置为0.75以下大致可以实现剔除操作,但是由于网络不稳定因素,存在心跳异常,所以该值尽量设置小于0.75多点,如0.5。为什么默认会0.85呢,我觉得应该是有算法支撑,但从结果来看,保护模式还是适用于大规模的服务集群,当一台或几台挂掉之后,也不会进入保护模式,默认比例下,可以实现实例的剔除。如果集群较小,如2台,挂掉一台就会进入保护模式,且保护模式意义不大,可以关闭自我保护模式。
  2. 通过设置实例的心跳时间,改为较小的周期。由于需要判断每分钟实际心跳数>实例总数*2*0.85,才不会进入自我保护模式,所以设置心跳周期较小,使实际心跳数多于比例下的心跳数,可以实现实例的及时剔除。实例的心跳周期设置:eureka.instance.lease-renewal-interval-in-seconds,如设置为5等等,具体可根据以上算法来计算合适的值。

Spring Cloud Eureka的自我保护模式与实例下线剔除的更多相关文章

  1. Spring Cloud Eureka 自我保护机制

    Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果 ...

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

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

  3. spring cloud Eureka常见问题总结

    Spring Cloud中,Eureka常见问题总结. 指定Eureka的Environment 1 eureka.environment: 指定环境 参考文档:https://github.com/ ...

  4. 第三章 服务治理:Spring Cloud Eureka

    Spring Cloud Eureka是Spring Cloud Netflix 微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能.Spri ...

  5. 【SpringCloud微服务实战学习系列】服务治理Spring Cloud Eureka

    Spring Cloud Eureka是Spring Cloud Netflix微服务中的一部分,它基于NetFlix Sureka做了二次封装,主要负责完成微服务架构中的服务治理功能. 一.服务治理 ...

  6. Eureka的自我保护模式

    一 Eureka的自我保护模式 进入自我保护模式最直观的体现就是Eureka Server首页的警告,如下图: 默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,E ...

  7. 服务治理-> Spring Cloud Eureka

    服务治理->搭建服务注册中心 服务治理可以说是微服务架构中最为核心和基础的模块, 它主要用来实现各个微服务 实例的自动化注册与发现. 为什么我们在微服务架构中那么需要服务治理模块呢?微服务 系统 ...

  8. SpringCloud系列六:Eureka的自我保护模式、IP选择、健康检查

    1. 回顾 前面讲了很多Eureka的用法,比如Eureka Server.Eureka Server的高可用.Eureka Server的用户认证(虽然未完全实现).元数据等, 这章将讲解剩下的自我 ...

  9. Spring Cloud Eureka 服务注册中心(二)

    序言 Eureka 是 Netflix 开发的,一个基于 REST 服务的,服务注册与发现的组件 它主要包括两个组件:Eureka Server 和 Eureka Client Eureka Clie ...

随机推荐

  1. [Go] gocron源码阅读-go语言中数组和切片的字面值初始化语法

    源码中有这么一句,这个函数要求返回的是[]cli.Command,cli.Command类型的切片,这个地方直接使用字面值初始化了一个切片返回去了 return []cli.Command{comma ...

  2. localStorage在不同页面之间的设置值与取值--加密 localStorage与解密localStorage

    在aa.vue页面 <template> <div> <h1>在aa页面设置值</h1> <button @click="shezhi& ...

  3. 卷积核filter和kernal的区别

    在一堆介绍卷积的帖子中,这篇特别之处在于很萌的示例配色,令人眼前一亮,当然直观也是很直观滴,保证了能在昏昏欲睡见周公子前看完. https://towardsdatascience.com/types ...

  4. layui教程---table

    layui.config({ base: "${ctx}/static/js/" }).use(['form', 'layer', 'jquery', 'common','elem ...

  5. cicros安装

    1.下载与安装依赖包 wget https://github.com/libgd/libgd/releases/download/gd-2.2.5/libgd-2.2.5.tar.gz tar zxv ...

  6. vue v-show的使用

    v-show的功能和v-if基本一样,但是v-if有衍生的v-else-if和v-else,v-show没有 v-show的性能比v-if要好,能用v-show就不要用v-if v-if是删除dom节 ...

  7. 【BZOJ4556】[TJOI2016&HEOI2016] 字符串(后缀自动机+线段树合并+二分)

    点此看题面 大致题意: 给你一个字符串\(s\),每次问你一个子串\(s[a..b]\)的所有子串和\(s[c..d]\)的最长公共前缀. 二分 首先我们可以发现一个简单性质,即要求最长公共前缀,则我 ...

  8. AtCoder Grand Contest 036

    Preface 这篇已经鸽了好久的说,AGC037都打完了才回来补所以题目可能都记不大清楚了,如有错误请指正 这场感觉难度远高于上一场,从D开始就不会了,E没写(看了题解都不会写),F就是抄曲明姐姐的 ...

  9. Java 基础系列:不变性

    1.1 定义 不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量. 可变类(Mutable Objects):类的实例创建后,可以修改其内容. ...

  10. 【Linux命令】Linux压缩及解压命令

    Linux压缩及解压命令 一.文件打包和压缩命令介绍 linux系统文件压缩格式,常用的有*.tar.gz.*.gz.*.zip.*.tar,还有*.rar..7z..bz2..tar.xz..tar ...