【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码

news2025/4/22 11:39:00

文章目录

    • 前言
    • 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()的最后要去清除特定信息下的缓存,这是为了确保在注册实例后,缓存中的信息是最新的。由于注册实例可能导致缓存中的信息过时,因此需要在注册后进行缓存的重置,以便在下一次访问时能够获取最新的实例信息。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32入门教程-2023版【3-2】使用库函数点亮GPIO灯

关注 点赞 不错过精彩内容 大家好,我是硬核王同学,最近在做免费的嵌入式知识分享,帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 二、正式点亮一个LED灯 (3)使用库函数点亮GPIO灯 RCC初始化 首先用的是&…

【Java | 多线程案例】定时器的实现

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习JavaEE的一点学习心得,欢迎大家在评论区交流讨论💌 这里写…

“推荐大战:抖音vs.快手”——背后的秘密全揭晓!

大家好,我是小米,一个热衷于技术分享的小伙伴。最近在面试的时候遇到了一个非常有趣的问题,也是很多人关心的话题——字节跳动产品面试题:说一下抖音和快手的推荐策略有什么不同?今天,就让我们一起来揭开这…

前端vue uni-app使用Vue和ECharts构建交互式树形结构图

题目:使用Vue和ECharts构建交互式树形结构图 摘要:本文介绍了如何使用Vue.js和ECharts构建一个交互式的树形结构图。通过整合ECharts的强大可视化功能,我们创建了一个可拖拽移动、点击展开和收缩的树形结构图,并实现了无限添加子…

《Spring Cloud学习笔记:微服务保护Sentinel + JMeter快速入门》

Review 解决了服务拆分之后的服务治理问题:Nacos解决了服务治理问题OpenFeign解决了服务之间的远程调用问题网关与前端进行交互,基于网关的过滤器解决了登录校验的问题 流量控制:避免因为突发流量而导致的服务宕机。 隔离和降级&#xff1a…

Java EE Servlet之Servlet API详解

文章目录 1. HttpServlet1.1 核心方法 2. HttpServletRequest3. HttpServletResponse 接下来我们来学习 Servlet API 里面的详细情况 1. HttpServlet 写一个 Servlet 代码,都是要继承这个类,重写里面的方法 Servlet 这里的代码,只需要继承…

【数据结构】第2章线性表(头歌习题)【合集】

文章目录 第1关:实现顺序表各种基本运算的算法任务描述编程要求完整代码 第2关:实现单链表各种基本运算的算法任务描述编程要求完整代码 第3关:移除顺序表中所有值等于x的元素任务描述编程要求完整代码 第4关:逆置顺序表任务描述编…

穷举vs暴搜vs深搜vs回溯vs剪枝

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析(3) 目录 👉🏻全排列👉&#…

使用WSL

一、下载 Microsoft Store下载Ububtu,然后点击打开 二、报错WslRegisterDistribution failed with error: 0x800701bc 解决办法: 1、开启Windows Subsystem for Linux dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linu…

Unity之组件的生命周期

PS:第二天,依旧在摸鱼学unity 一、组件的概念 我本身是由Web后端转到了游戏后端,最近因为工作原因在学ET框架。学到了 ECS 编程模式开发(E —— Entity,C —— Component , S —— System)实体、…

玩转MYSQL|详细分析mysql-MGR集群搭建

目录 1、简介 2、环境准备 2.1 数据库服务器规划 2.2 安装mysql5.7.20 2.3 设置hostname和ip映射 3、创建复制环境 3.1 服务器host68.cn 3.1.1 配置/etc/my.cnf 3.1.2 服务器host68.cn上建立复制账号: 3.1.3 在mysql服务器host68.cn上安装group replicatio…

docker搭建minio集群,集群分享文件URL踩坑问题

一、环境准备 3台机器,Ip地址依次为IP1,IP2,IP3二、设置服务器时间同步 Minio集群需要各个节点的时间保持同步,使用NTP作为时间同步服务,这里以Minio-1(IP1)为上游服务器,其它2个节点为下游服务器&#x…

idea实现Java连接MySQL数据库

1.下载MySQL并安装 首先如果没有mysql的需要先下载MySQL,可以看这个教程: Mysql超详细安装配置教程(保姆级)_mysql安装及配置超详细教程-CSDN博客 2.下载mysql 的jdbc驱动 官网:MySQL :: Download Connector/J 解压并将驱动jar包导入id…

信息网络协议基础_IP移动网络管理

文章目录 概述移动IPv6待解决的问题关键词基本过程分组拦截技术移动检测和转交地址自动配置到家乡代理绑定注册通信对端不支持IPv6通信对端支持移动IPv6 对IP以上层屏蔽移动性 移动IPv6存在的问题移动IPv6优化代理移动IP概述原理基本过程初始接入切换 概述 移动IPv6 待解决的问…

证明:切线垂直于半径

证明: 切线垂直于过切点的半径。 下面是网上最简单的证明方法。 证明: 利用反证法。 如下图所示,直线AB和圆O切于点A,假设OA 不垂直于 AB,而 O B ⊥ A B OB \perp AB OB⊥AB,则 ∠ O B A 90 \angle OB…

Apache SSI 远程命令执行漏洞

一、环境搭建 二、访问upload.php 三、写shell <!--#exec cmd"id" --> 四、访问 如图所示&#xff0c;即getshell成功&#xff01;​

C#上位机与欧姆龙PLC的通信06---- HostLink协议(FINS版)

1、介绍 对于上位机开发来说&#xff0c;欧姆龙PLC支持的主要的协议有Hostlink协议&#xff0c;FinsTcp/Udp协议&#xff0c;EtherNetIP协议&#xff0c;本项目使用Hostlink协议。 Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令&#xff0c;可…

Spring Cloud Gateway集成Knife4j

1、前提 网关路由能够正常工作。 案例 基于 Spring Cloud Gateway Nacos 实现动态路由拓展的参考地址&#xff1a;Spring Cloud Gateway Nacos 实现动态路由 详细官网案例&#xff1a;https://doc.xiaominfo.com/docs/middleware-sources/spring-cloud-gateway/spring-gatewa…

使用anaconda创建爬虫spyder工程

1.由于每个工程使用的环境都可能不一样&#xff0c;因此一个好的习惯就是不同的工程都创建属于自己的环境&#xff0c;在anaconda中默认的环境是base&#xff0c;我们现在来创建一个名为spyder的环境&#xff0c;专门用于爬虫工程&#xff1a; //括号中名字&#xff0c;代表当…

【网络安全 | Misc】Aesop_secret(ISCC)

正文 动态gif&#xff0c;使用工具进行分解&#xff1a; https://tu.sioe.cn/gj/fenjie/ 得到ISCC字样 由Winhex看到密文&#xff1a; U2FsdGVkX19QwGkcgD0fTjZxgijRzQOGbCWALh4sRDec2w6xsY/ux53Vuj/AMZBDJ87qyZL5kAf1fmAH4Oe13Iu435bfRBuZgHpnRjTBn5xsDHONiR3t0Oa8yG/tOKJMN…