【SpringCloud】Eureka源码解析 下

e246a1dda09849a5a89535a62441565d.png

eurkea是一个服务发现与注册组件,它包含客户端和服务端,服务端负责管理服务的注册信息,客户端用于简化与服务端的交互。上一章分析了eureka的服务注册,这一章来分析eureka的心跳机制

参考源码:<spring-cloud.version>Hoxton.SR9</spring-cloud.version>

上一章:【SpringCloud】Eureka源码解析 上-CSDN博客

1、心跳机制

eureka的客户端会持续向服务端发送心跳,这个定时动作就是心跳机制。根据上一章的分析,我们合理推测定时任务和initScheduledTasks方法有关。查看DiscoveryClient类的initScheduledTasks方法,详情如下

private void initScheduledTasks() {
	...
	// 心跳定时任务,具体任务在HeartbeatThread内
	this.heartbeatTask = new TimedSupervisorTask("heartbeat", this.scheduler, this.heartbeatExecutor, renewalIntervalInSecs, TimeUnit.SECONDS, expBackOffBound, 
	new HeartbeatThread());
		this.scheduler.schedule(this.heartbeatTask, (long)renewalIntervalInSecs, TimeUnit.SECONDS);
	...  
}

private class HeartbeatThread implements Runnable {
	private HeartbeatThread() {
	}

	public void run() {
		// 续约
		if (DiscoveryClient.this.renew()) {
			DiscoveryClient.this.lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis();
		}
	}
}

boolean renew() {
	...
	// 发送心跳
	EurekaHttpResponse<InstanceInfo> httpResponse = this.eurekaTransport.registrationClient.sendHeartBeat(this.instanceInfo.getAppName(), this.instanceInfo.getId(), this.instanceInfo, (InstanceInfo.InstanceStatus)null);
	...
}

2、剔除服务

注册列表中的服务超过一定时间没有续约,eureka服务端就会将该服务从注册列表中剔除,剔除服务同样用到了定时任务

调用链:EurekaServerInitializerConfiguration.start
-> EurekaServerBootstrap.contextInitialized
-> initEurekaServerContext
-> PeerAwareInstanceRegistryImpl.openForTraffic
-> AbstractInstanceRegistry.postInit
protected void postInit() {
	...
	// 定时剔除任务,具体任务在EvictionTask内
	this.evictionTaskRef.set(new EvictionTask());
	this.evictionTimer.schedule((TimerTask)this.evictionTaskRef.get(), this.serverConfig.getEvictionIntervalTimerInMs(), this.serverConfig.getEvictionIntervalTimerInMs());
	...
}

class EvictionTask extends TimerTask {
	...
	public void run() {
		// 具体的剔除任务
		AbstractInstanceRegistry.this.evict(compensationTimeMs);
	}
}

// 剔除方法
public void evict(long additionalLeaseMs) {
	logger.debug("Running the evict task");
	// 是否启用心跳保护机制
	if (!this.isLeaseExpirationEnabled()) {
		logger.debug("DS: lease expiration is currently disabled.");
	} else {
		...
		int registrySize = (int)this.getLocalRegistrySize();
		// 根据阈值计算可以被剔除的服务最大数量
		int registrySizeThreshold = (int)((double)registrySize * 
		this.serverConfig.getRenewalPercentThreshold());
		// 剔除后剩余最小数量
		int evictionLimit = registrySize - registrySizeThreshold;
		// 计算两者的最小值,剔除较小数量的服务实例
		int toEvict = Math.min(expiredLeases.size(), evictionLimit);
		if (toEvict > 0) {
		   for(int i = 0; i < toEvict; ++i) {
		   ...
		   // 执行删除动作
		   this.internalCancel(appName, id, false);
		   ...
		}
	}
}

3、保护机制

eureka服务端在短时间内丢失大量客户端时,会启用自我保护模式。在保护模式下,eureka服务端不会剔除服务,直到故障恢复后,eureka服务端才会退出保护模式

eureka的自我保护机制和剔除服务相关,找到AbstractInstanceRegistry类postInit服务剔除方法

 // 剔除方法
public void evict(long additionalLeaseMs) {
	// 是否允许剔除服务
	if (!this.isLeaseExpirationEnabled()) {
	   ...
	}
}
public class PeerAwareInstanceRegistryImpl extends AbstractInstanceRegistry implements PeerAwareInstanceRegistry {
    
    public boolean isLeaseExpirationEnabled() {
        // 是否启用自我保护机制
        if (!this.isSelfPreservationModeEnabled()) {
            return true;
        } else {
            // 已启用保护机制
            // 实际续约个数大于最小续约个数时,允许服务剔除
            return this.numberOfRenewsPerMinThreshold > 0 && this.getNumOfRenewsInLastMin() > (long)this.numberOfRenewsPerMinThreshold;
        }
    }

    public boolean isSelfPreservationModeEnabled() {
        return this.serverConfig.shouldEnableSelfPreservation();
    }
}

4、总结

eureka客户端通过定时任务向服务端发送心跳完成续约,eureka服务端会从服务列表中剔除超时未续约的服务;若出现网络故障丢失大量服务端,eureka服务端会进入自我保护模式,不再剔除服务,直到故障修复

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/760750.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

科普文:八大排序算法(JAVA实现)+ 自制动画 (袁厨的算法小屋)

我将我仓库里的排序算法给大家汇总整理了一下&#xff0c;写的非常非常细&#xff0c;还对每个算法制作了动画&#xff0c;一定能够对大家有所帮助&#xff0c;欢迎大家阅读。另外我也对 leetcode 上面可以用排序算法秒杀的算法题进行了总结&#xff0c;会在后面的文章中进行发…

OpenCV 调用自定义训练的 YOLO-V8 Onnx 模型

一、YOLO-V8 转 Onnx 在本专栏的前面几篇文章中&#xff0c;我们使用 ultralytics 公司开源发布的 YOLO-V8 模型&#xff0c;分别 Fine-Tuning 实验了 目标检测、关键点检测、分类 任务&#xff0c;实验后发现效果都非常的不错&#xff0c;但是前面的演示都是基于 ultralytics…

计算机组成原理——寄存器

文章目录 1. 寄存器 2. 带寄存器的加法器 3. 时钟信号与计算速度 1. 寄存器 上一篇D触发器可以在时钟上沿存储1位数据。如果想存储多个位&#xff08;bit&#xff09;的数据&#xff0c;就需要用多个D触发器并联实现&#xff0c;这种电路称之为寄存器。 寄存器是计算机中央…

MATLAB使用系统辨识工具箱建立PID水温的传递函数系数

概述 利用PID控制水温&#xff0c;由于实际在工程项目中&#xff0c;手动调节PID参数比较耗费时间&#xff0c;所以可以先利用MATLAB中的Simulink软件建立模型&#xff0c;先在仿真软件上调节大概的PID参数&#xff0c;再利用此PID参数为基础在实际的工程项目中手动调节PID参数…

spring boot(学习笔记第十一课)

spring boot(学习笔记第十一课) Session共享&#xff0c;JPA实现自动RESTful 学习内容&#xff1a; Session共享JPA实现自动RESTful 1. Session共享 Session共享面临问题 spring boot默认将session保存在web server的内存里面&#xff0c;会产生什么问题呢。 如上图所示&#…

《昇思25天学习打卡营第15天 | 昇思MindSpore基于MindSpore的红酒分类实验》

15天 本节学了通过MindSpore的完成红酒分类。 1.K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;是机器学习最基础的算法之一。 1.1分类问题 1.2回归问题 1.3距离的定义 2.数据处理 2.1 数据准备 2.2 数据读取与处…

isupper()方法——判断字符串是否全由大写字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 isupper()方法用于判断字符串中所有的字母是否都是大写。isupper()方法的语法格式如下&#xff1a; str.isupper() 如果字符串中包含至少…

OpenGL3.3_C++_Windows(24)

渲染平行光阴影 阴影作用&#xff1a; 有了阴影的渲染&#xff0c;更容易地区分出物体之间的位置关系&#xff0c;如何判断片段是否在阴影中&#xff1f; 普通思路&#xff1a; 以光的位置为视角进行渲染&#xff0c;我们绘制一条从光源出发的射线&#xff0c;测试更新射线经过…

数据结构-分析期末选择题考点(广义表)

莫道桑榆晚 为霞尚满天 数据结构-图期末选择题 数据结构-串、数组选择题 数据结构-排序选择题 数据结构-线性表、栈、队列、二叉树合集 契子✨ 广义表&#xff1a; <1>考点一&#xff1a;基本概念 广义表的基础概念 &#xff08;1&#xff09;什么是广义表 广义表&#…

小韩厂涨乌托邦公式源码

小韩厂涨&乌托邦&公式源码已经测试通过,可以发布云平台自行编辑 DRAWGBK(C>0, RGB(50,60,250),RGB(17,21,89),0,11,0); H1:=MAX(DYNAINFO(3),DYNAINFO(5)); L1:=MIN(DYNAINFO(3),DYNAINFO(6)); P1:=H1-L1; 阻力:=L1+P1*7/8,COLORGREEN; 支撑:=L1+P1*0.5/8,COLORRED;…

超详细的 C++中的封装继承和多态的知识总结<1.封装>

引言 小伙伴们都知道C面向对象难&#xff0c;可是大家都知道&#xff0c;这个才是C和C的真正区别的地方&#xff0c;也是C深受所有大厂喜爱的原因&#xff0c;它的原理更接近底层&#xff0c;它的逻辑更好&#xff0c;但是学习难度高&#xff0c;大家一定要坚持下来呀&#xff…

如何做好一个企业家IP:塑造独特的个人品牌

在当今数字化时代&#xff0c;个人品牌的力量愈发凸显&#xff0c;对于企业家而言&#xff0c;一个强大的IP&#xff08;Intellectual Property&#xff0c;即知识产权或个人品牌&#xff09;不仅有助于提升个人影响力&#xff0c;还能为企业的发展注入强大动力。那么&#xff…

Flutter【组件】点击类型表单项

简介 flutter 点击表单项组件&#xff0c;适合用户输入表单的场景。 点击表单项组件是一个用户界面元素&#xff0c;通常用于表单或设置界面中&#xff0c;以便用户可以点击它们来选择或更改某些设置或输入内容。这类组件通常由一个标签和一个可点击区域组成&#xff0c;并且…

【后端面试题】【中间件】【NoSQL】ElasticSearch索引机制和高性能的面试思路

Elasticsearch的索引机制 Elasticsearch使用的是倒排索引&#xff0c;所谓的倒排索引是相对于正排索引而言的。 在一般的文件系统中&#xff0c;索引是文档映射到关键字&#xff0c;而倒排索引则相反&#xff0c;是从关键字映射到文档。 如果没有倒排索引的话&#xff0c;想找…

基于51单片机的篮球计时器Proteus仿真

文章目录 一、篮球计时器1.题目要求2.思路3.仿真图3.1 未仿真时3.2 仿真开始3.3 A队进分3.4 B队进分3.5 比赛结束 4.仿真程序4.1 主函数4.2 时间显示4.3 比分显示4.4 按键扫描 二、总结 一、篮球计时器 1.题目要求 以51单片机为核心&#xff0c;设计并制作篮球计时器 基本功…

数据结构:期末考 第六次测试(总复习)

一、 单选题 &#xff08;共50题&#xff0c;100分&#xff09; 1、表长为n的顺序存储的线性表&#xff0c;当在任何位置上插入或删除一个元素的概率相等时&#xff0c;插入一个元素所需移动元素的平均个数为&#xff08; D &#xff09;.&#xff08;2.0&#xff09; A、 &am…

基于matlab的可乐标签模板匹配

1 建模思路 1.图像预处理&#xff1a; 如果目标图像和模板图像是彩色的&#xff08;即RGB图像&#xff09;&#xff0c;则将它们转换为灰度图像&#xff0c;以便在单通道上进行匹配。使用rgb2gray函数进行灰度化。 2.获取模板大小&#xff1a; 使用size函数获取模板图像的高…

骁龙相机拍照流程分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 1.deliverInputEvent 拍照点击事件处理 2.submitRequestList Camera 提交拍照请求 3.createCaptureRequest 拍照请求帧数 骁龙相机通过binder 数据传输…

2006-2020上市公司研发投入金额数据集

2006-2020上市公司研发投入金额数据集https://download.csdn.net/download/a519573917/89501035 目录 上市公司研发投入与企业绩效的关系研究 一、引言 二、文献综述 三、研究设计 四、实证结果与分析 &#xff08;一&#xff09;描述性统计分析 &#xff08;二&#xf…