Spring Cloud Eureka的自我保护模式与实例下线剔除
之前我说明了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分钟刷新一次。
通过上面分析,我们大致了解了不通过关闭自我保护模式下触发服务剔除操作的条件。得出以下两种方案来实现失效节点的剔除(亲测有效)。
- 通过修改每分钟心跳成功最低比例来控制注册中心不进入自我保护模式,实时剔除节点(需要等到实例定义的过期时间,且注册中心触发刷新周期)。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*0.85,才不会进入自我保护模式,所以设置心跳周期较小,使实际心跳数多于比例下的心跳数,可以实现实例的及时剔除。实例的心跳周期设置:eureka.instance.lease-renewal-interval-in-seconds,如设置为5等等,具体可根据以上算法来计算合适的值。
Spring Cloud Eureka的自我保护模式与实例下线剔除的更多相关文章
- Spring Cloud Eureka 自我保护机制
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果 ...
- Spring Cloud Eureka 自我保护机制实战分析
前些天栈长在Java技术栈微信公众号分享过 Spring Cloud Eureka 的系列文章: Spring Cloud Eureka 自我保护机制 Spring Cloud Eureka 常用配置 ...
- spring cloud Eureka常见问题总结
Spring Cloud中,Eureka常见问题总结. 指定Eureka的Environment 1 eureka.environment: 指定环境 参考文档:https://github.com/ ...
- 第三章 服务治理:Spring Cloud Eureka
Spring Cloud Eureka是Spring Cloud Netflix 微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理功能.Spri ...
- 【SpringCloud微服务实战学习系列】服务治理Spring Cloud Eureka
Spring Cloud Eureka是Spring Cloud Netflix微服务中的一部分,它基于NetFlix Sureka做了二次封装,主要负责完成微服务架构中的服务治理功能. 一.服务治理 ...
- Eureka的自我保护模式
一 Eureka的自我保护模式 进入自我保护模式最直观的体现就是Eureka Server首页的警告,如下图: 默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,E ...
- 服务治理-> Spring Cloud Eureka
服务治理->搭建服务注册中心 服务治理可以说是微服务架构中最为核心和基础的模块, 它主要用来实现各个微服务 实例的自动化注册与发现. 为什么我们在微服务架构中那么需要服务治理模块呢?微服务 系统 ...
- SpringCloud系列六:Eureka的自我保护模式、IP选择、健康检查
1. 回顾 前面讲了很多Eureka的用法,比如Eureka Server.Eureka Server的高可用.Eureka Server的用户认证(虽然未完全实现).元数据等, 这章将讲解剩下的自我 ...
- Spring Cloud Eureka 服务注册中心(二)
序言 Eureka 是 Netflix 开发的,一个基于 REST 服务的,服务注册与发现的组件 它主要包括两个组件:Eureka Server 和 Eureka Client Eureka Clie ...
随机推荐
- Django 的ORM 表间操作
Django之ORM表间操作 之前完成了简单的数据库数据增加操作.这次学习更多的表间操作. 单表操作 增加 方式一 b = Book(title="Python基础", pub ...
- Java重定向标准输入/输出
在System类中提供了三个重定向标准输入/输出的方法static void setErr(PrintStream err) 重定向“标准”错误输出流static void setIn(InputSt ...
- Bn Bp Binder native层关系
Servicemanager 源码在/frameworks/base/cmds/servicemanager/service_manager.c 编译成 systemmanager 可执行文件 sys ...
- 【洛谷P4589】[TJOI2018]智力竞赛(二分+最小链覆盖)
洛谷 题意: 给出一个\(DAG\),现在要选出\(n+1\)条可相交的链来覆盖,最终使得未被覆盖的点集中,权值最小的点的权值最大. 思路: 显然最终的答案具有单调性,故直接二分答案来判断: 直接将小 ...
- node exporter
在prometheus中负责数据汇报的程序统一叫做exporter; 负责主机信息收集的node_exporter 可以利用prometheus的static_configs来拉取node_expor ...
- django内容回顾:
Django 下载安装 命令行 pip install django==1.11.26 -i 源 pycharm 创建项目 命令行 django-admin startproject 项目名 pych ...
- 肖哥讲jquery:
jquery 是一个模块 一个库 js封装的一个库 导入jq <script src="jquery.js"></script> <script ...
- Shiro内置过滤器
Shiro内置过滤器 DefaultFilter 枚举类定义了shiro所有的默认过滤器. package org.apache.shiro.web.filter.mgt; public enum D ...
- 将mysql主键id从1开始 变为自增
在变为自增前,为了保证数据的安全性我们先将表中的数据备份一份,备份是通过mysql命令进行备份,如果已经安装mysql可视化工具navicat也可右键完成备份 1.备份表结构 create table ...
- mysql小知识点汇总---(时间与时间戳的转换, 修改mysql用户名密码, navicate 导入sql文件报错 1153)
1. 时间与时间戳的转换 1.1 时间戳转时间 FROM_UNIXTIME(add_time, '%Y-%m-%d') 1.2 时间转时间戳 UNIX_TIMESTAMP('2015-04-29') ...