【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码
文章目录
- 前言
- 1.@EnableEurekaServer
- 2.初始化缓存
- 3.jersey应用程序构建
- 3.1注册jeseryFilter
- 3.2构建JerseyApplication
- 4.处理注册请求
- 5.registry()
前言
前段时间遇到了一个业务问题就是k8s滚动发布Eureka微服务的过程中接口会有很多告警,当时想着应该是Ribbon没有同步到实时的Eureka缓存,导致列表中存在下线服务,于是通过Redis手动更新了Ribbon缓存(详细实现可以见上篇文章:通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题)但是那样的方式存在一个弊端即更新缓存的操作并不是“服务下线“这一动作来驱动,而是服务调用方发送请求才会触发(虽然用AOP可以做到无入侵式,不影响业务代码,但却或多或少会影响业务接口耗时)如果不能定位到准确的告警接口,此举会“牵一发而动全身”。基于此我也想过替代方案,比如Eureka-Server端存在两个监听器:
@EventListener
public void listen(EurekaInstanceCanceledEvent event){log.debug(event.getServerId()+"\t"+event.getAppName()+"服务下线");
}
@EventListener
public void listen(EurekaInstanceRegisteredEvent event){InstanceInfo instanceInfo = event.getInstanceInfo();log.debug(instanceInfo.getId()+"\t"+instanceInfo.getAppName()+"进行注册");
}

可以实时监听Eureka-Client端的注册情况,通过这样一种"服务实时上下线"的事件来驱动,可以完全确保每一次服务上下线都会伴随Ribbon缓存的更新。这样对业务接口就没有了影响,但理想很丰满现实很骨感,在实际中更新的操作不能执行。
当然也引入了MQ让服务调用方模拟消费者,让服务被调用方模拟生产者来效仿监听器的效果去清理缓存同样也是失败了…
所以对于每一个服务Eureka到底采取的是什么样的方式来进行注册,分发,我想借今天这个机会来好好整理一下:
EurekaServer是Netflix开源的服务注册和发现组件,它可以管理和监控集群中各个微服务实例的状态,并提供服务注册、发现和负载均衡的功能。EurekaServer存储了所有可用服务的实例,并根据负载情况将请求转发到不同的实例。
同样地,分析源码前先从整体流程图入手(手图):

1.@EnableEurekaServer
先从入口开始,由于受到了SpringCoud的整合,通过一个注解@EnableEurekaServer就将进程标志成为了服务注册和发现的组件:

关键点@Import(EurekaServerMarkerConfiguration.class)将该配置类纳入当前的配置中,使得Eureka服务器能够正常运行并提供相关的服务注册和发现功能,进入到EurekaServerMarkerConfiguration中:

发现在该类中存在一个象征性的Marker类并且被实例化作为Bean注册到了IOC容器中,这让我联想到了ArrayList之所以能够支持元素的随机访问也是因为实现了一个名为RandomAccess的接口,并且该接口下无声明无实现。可谓是有异曲同工之妙~

回归正题,注释中写到此Bean用于作为标记来加载一个自动配置类:EurekaServerAutoConfiguration,那为什么当加载该自动配置类之后就可以作为服务注册的中间件呢?在这过程中有着以下一系列动作:
2.初始化缓存
EurekaServerContext
在EurekaServerContext(Eureka-Server上下文)的实现类DefaultEurekaServerContext中存在一个initialize()方法用于进行服务端的初始化工作:

主要是初始化Eureka-Server各个节点间的一些基础信息,在这之中特别重要的是在init()方法中初始化了Eureka-server端的响应缓存:

可以看到的是为了在多线程环境下对于变量responseCache安全初始化,方法加上了synchronized来修饰,初始化的方法也比较直接,传入了配置信息与注册请求就完成了缓存初始化,在该类的有参构造中,做了以下动作:

对Eurek-Server开启debug,在Register()方法入口打上断点,启动一个Eurek-Client服务,立即就触发了注册流程,也就是在Eureka-Server核心的一个类AbstractInstanceRegistry中,也是在这个类中一级缓存registry得到了初始化:

3.jersey应用程序构建
3.1注册jeseryFilter
当上线的微服务要进行注册,他会发送Http注册请求到注册中心中,“不是mvc胜似mvc”但还是存在一点点差异:
服务端的请求入口是基于Jersey(类似mvc的web层框架)的RestFul方式,当服务上线,会发送http注册请求到Eureka-Server中,该请求会被Eureka内部的控制层框架Jesery中的过滤器拦截(和SpringMVC非常相似)过滤所有的注册请求,过滤器的注册发生在自动加载配置类的过程中:

JeseryFilter拦截注册请求的行为:

3.2构建JerseyApplication
当对Eureka-Server中的EurekaServerAutoConfiguration类debug,在该方法中打上断点,他将Eureka服务器所需的资源构建Jersey应用程序对象

并将返回值作为参数传递到jerseyFilterRegistration()中作为构建Jersey filter的必要条件

至此Filter构建完成
Eureka所进行的心跳连接,服务剔除,服务注册,自我保护都是通过发送http请求的形式,而这些都会被Jersey的过滤器所拦截随即分发到具体的处理类上(类似于Controller)只不过在Eureka中是被名为Resource的处理类来处理,有了他Eureka-Client发送的注册请求才会被分发处理
4.处理注册请求
注册请求被Jesery拦截,在ApplicationResource类中被处理,就像MVC中的Controller一样在这一层中主要是对Eureka-Client发来的请求做一些校验工作,最后调用实质的注册方法

其实这不重要,因为他最终还是去调用了Register()换一个断点:
5.registry()
紧接着就是注册流程registry()开启,开始注册请求的服务实例信息:

为什么在register()的最后要去清除特定信息下的缓存,这是为了确保在注册实例后,缓存中的信息是最新的。由于注册实例可能导致缓存中的信息过时,因此需要在注册后进行缓存的重置,以便在下一次访问时能够获取最新的实例信息。
相关文章:
【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码
文章目录 前言1.EnableEurekaServer2.初始化缓存3.jersey应用程序构建3.1注册jeseryFilter3.2构建JerseyApplication 4.处理注册请求5.registry() 前言 前段时间遇到了一个业务问题就是k8s滚动发布Eureka微服务的过程中接口会有很多告警,当时…...
Java 代理模式
一、代理模式概述 代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。 代理模式的主要作用是扩展目标…...
【Java干货教程】JSON,JSONObject,JSONArray类详解
一、定义 JSON:就是一种轻量级的数据交换格式,被广泛应用于WEB应用程序开发。JSON的简洁和清晰的层次结构,易于阅读和编写;同时也易于机器解析和生成,有效的提升网络传输效率;支持多种语言,很多…...
2023年高级软考系统架构师考题参考
对于一些有实践经验的同学来说,感觉不难,但是落笔到纸面上,就差强人意了,平时这方面要多练习,所想所思要落到纸面上,或者表达清晰让别人听懂,不仅是工作中的一个基本素质,也是个非常…...
【c语言】飞机大战(1)
提前准备好游戏要的素材,可以到爱给网去找,飞机大战我们需要的是一个我方战机图片,一个背景图,三个敌方战机的图,我方战机的图片,敌方战机的图片,并且将图片和.cpp放在同一文件夹下. 这里创建.…...
关于 K8s 的一些基础概念整理
〇、前言 Kubernetes,将中间八个字母用数字 8 替换掉简称 k8s,是一个开源的容器集群管理系统,由谷歌开发并维护。它为跨主机的容器化应用提供资源调度、服务发现、高可用管理和弹性伸缩等功能。 下面简单列一下 k8s 的几个特性: 自…...
Node.js-fs、path、http模块
1.初识Node.js 1.1 什么是Node.js 1.2 Node.js中的JavaScript运行环境 1.3 Node.js可以做什么 Node.js 作为一个JavaScript 的运行环境,仅仅提供了基础的功能和 AP1。然而,基于 ode.s 提供的这些基础能,很多强大的工具和框架如雨后春笋&…...
CentOS 安装WebLogic
1.JDK 安装 cd /home/ mkdir java cd java/ tar -zxvf jdk-8u321-linux-x64.tar.gzvim /etc/profile添加以下内容到 /etc/profile JAVA_HOME/home/java/jdk1.8.0_321 CLASSPATH.:$JAVA_HOME/lib.tools.jar PATH$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH刷新配置…...
Linux命令的操作练习
1.创建ss别名,查看长格式详细信息 alias ssls -l 2.创建ss别名,复制boot文件夹下的内容到data文件夹下 alias sscp -r /boot /data 3.删除别名ss unalias ss 4. 复制test文件夹下的passwd文件到qq文件夹下,并改名为ww cp test/pas…...
杰发科技AC7840——EEPROM初探
0.序 7840和7801的模拟EEPROM使用不太一样 1.现象 按照官方Demo,在这样的配置下,我们看到存储是这样的(连续三个数字1 2 3)。 使用串口工具的多帧发送功能 看不出多少规律 修改代码后 发现如下规律: 前四个字节是…...
WPF 基础入门(简介)
简介 WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分。它提供了统一的编程模型、语言和框架,真正做到了分离界面设计人员与开发人员的工作;同时它提供了…...
【Unity动画系统】Animator有限状态机参数详解
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:Uni…...
php获取访客IP、UA、操作系统、浏览器等信息
最近有个需求就是获取下本地的ip地址、网上搜索了相关的教程,总结一下分享给大家、有需要的小伙伴可以参考一下 一、简单的获取 User Agent 信息代码: echo $_SERVER[HTTP_USER_AGENT]; 二、获取访客操作系统信息: /** * 获取客户端操作系统信息,包括win10 * pa…...
基于huffman编解码的图像压缩算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Huffman编码算法步骤 4.2 Huffman编码的数学原理 4.3 基于Huffman编解码的图像压缩 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..…...
python+django网上购物商城系统o9m4k
语言:Python 框架:django/flask可以定制 软件版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发工具pycharm/vscode都可以 前端框架:vue.js 系统使用过程主要涉及到管理员和用户两种角色,主要包含个…...
面试题-性能优化
前端项目优化: 一般考虑方面: (挑几点记住) 我们学的: 懒加载: 路由、图片懒加载 骨架屏的使用 压缩文件:可以使用压缩工具(如GZIP)对页面文件进行压缩,减小文件大小,提高页面加载速度。 减少HTTP请求&a…...
自身文档管理规范
之前在 这里 叙述了 用 sphinx 生成静态网站, 并利用 静态网络托管服务 readthedocs 现在我们有了新的需求,想知道这些东西到底是什么。 过程 过程A : markdown/rst -> html mkdocs sphinx相关: pandoc(不能生成整个网站的h…...
php学习05-常量
常量可以理解为值不变的量。常量值被定义后,在脚本的其他任何地方都不能改变。一个常量由英文字母、下划线和数字组成,但数字不能作为首字母出现。 在PHP中使用define()函数来定义常量,该函数的语法格式如下: define(string cons…...
MFC:如何将JPEG等图片显示到对话框客户区
步骤: 0、打开VS2022创建一个基于对话框的MFC应用,项目名称命名为PicShow,创建完成后将对话框客户区中的"确定"按钮等内容删除(具体步骤略)。 1、建立菜单栏:文件->打开、退出。具体步骤&#x…...
MIUI解BL锁+刷系统教程
解除BL锁 打开设置找到My device->Detailed info and specs->连点5下MIUI version(进入开发者模式)重新打开设置找到Additional settings->Developer opentions->Mi lock status->Add account and device下载官方解锁工具包(miflash_unlock…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
