Eureka源码分析:Eureka不会进行二次Replication的原因

Spring Cloud Eureka源码分析之心跳续约及自我保护机制 Eureka-Server是如何判断一个服务不可用的? Eureka是通过心跳续约的方式来检查各个服务提供者的健康状态。 实际上,在判断服务不可用这个部分,会分为两块逻辑。 Eureka-Server需要定期检查服务提供者的健康状态。 Eureka-Client在运行过程中需要定期更新注册信息。 Eureka的心跳续约机制如下图所示。 客户端在启动时, 会开启一个心跳任务,每隔30s向服务单发送一次心跳请求。 服务端维护了每个实例的最后一次心跳时间,客户端发送心跳包过来后,会更新这个心跳 阅读详情

Eureka不会进行二次同步注册信息

Eureka会将本实例中的注册信息同步到它的peer节点上,这是我们都知道的特性。然而,当peer节点收到同步数据后,并不会将这些信息再同步到它自己的peer节点上。如果有A, B, C三个实例,A配B, B配C, C配A, 那么当向A注册一个新服务时,只有A, B两个Eureka实例会有新服务的注册信息,C是没有的。这一点在官方wiki上并没有明确说明。下面通过源码来查找一下原因。

构建

Eureka当前版本 (https://github.com/Netflix/eureka) 使用gradle作为构建工具,不过git仓库里提供了gradlew,所以也不用我们自己去下载。如果自己下载了gradle的最新版本3.X,那么反而会因为兼容性问题导致构建失败,因为官方使用的是2.1.0版本。构建之前一定要科学上网,否则很多依赖是下载不到的:

./gradlew build -x test // 跳过测试

源码定位与分析

Eureka本质上是一个Servlet应用,它使用jersey作为RESTful框架来构造自己的REST服务。在eureka-server模块中可以找到web.xml文件,在build/libs目录下可以看到构建完成后生成的war包。我们要找的代码,在eureka-core模块的com.netflix.eureka.resource包下。jersey相比SpringMVC来说它是一个更加标准的HTTP RESTful框架,因此很自然可以猜想到resource就是请求路由所在的包。

查阅官方wiki, 我们知道eureka对外暴露接口的形式为:

GET/POST/PUT/DELETE /eureka/v2/apps/{APP-ID}

我们在ApplicationsResource类中可以发现如下注解:

@Path("/{version}/apps")
@Produces({"application/xml", "application/json"})
public class ApplicationsResource {
    // ... ...
}

由此可以确定该类就是我们要找的重点。查阅该类,会发现有如下方法:

/**
     * Gets information about a particular {@link com.netflix.discovery.shared.Application}.
     *
     * @param version
     *            the version of the request.
     * @param appId
     *            the unique application identifier (which is the name) of the
     *            application.
     * @return information about a particular application.
     */
    @Path("{appId}")
    public ApplicationResource getApplicationResource(
            @PathParam("version") String version,
            @PathParam("appId") String appId) {
        CurrentRequestVersion.set(Version.toEnum(version));
        return new ApplicationResource(appId, serverConfig, registry); // 交给ApplicationResource处理
    }

通过注释得知该方法用来处理客户端查询某个服务信息的HTTP请求。但是方法体中并没有具体的查询逻辑,而是委托给了ApplicationReource类进行处理。查阅该类,可以发现注册信息的CRUD操作逻辑都是在这里实现的。我们重点关注一下注册方法,因为Eureka在收到新服务的注册信息时会马上将其同步到peer节点中:

@POST
    @Consumes({"application/json", "application/xml"})
    public Response addInstance(InstanceInfo info,
                                @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {
        logger.debug("Registering instance {} (replication={})", info.getId(), isReplication);
        // validate that the instanceinfo contains all the necessary required fields

        // 参数检查 ...

        // 调用注册逻辑
        registry.register(info, "true".equals(isReplication));
        return Response.status(204).build();  // 204 to be backwards compatible
    }

注意register的第二个参数:

"true".equals(isReplication)

isReplication是从请求头中获取的字符串,因此可以得知,Eureka在向peer节点发送同步请求时会在请求头中携带自定义的x-netflix-discovery-replication头:

public static final String HEADER_REPLICATION = "x-netflix-discovery-replication";

peer节点通过该请求头来判断当前请求是其它Eureka节点的同步请求还是服务的注册请求。我们假定当前请求是上一个Eureka发来的同步请求,那么这里第二个参数的值应该为true。

继续看register()方法,这是个PeerAwareInstanceRegistry接口的接口方法,该接口只有一个唯一实现PeerAwareInstanceRegistryImpl:

/**
     * Registers the information about the {@link InstanceInfo} and replicates
     * this information to all peer eureka nodes. If this is replication event
     * from other replica nodes then it is not replicated.
     *
     * @param info
     *            the {@link InstanceInfo} to be registered and replicated.
     * @param isReplication
     *            true if this is a replication event from other replica nodes,
     *            false otherwise.
     */
    @Override
    public void register(final InstanceInfo info, final boolean isReplication) {
        int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
        if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
            leaseDuration = info.getLeaseInfo().getDurationInSecs();
        }
        // 调用父类的实现执行注册逻辑
        super.register(info, leaseDuration, isReplication);
        // 将该注册请求同步到peer节点中
        replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
    }

首先通过英文注释可以了解到,如果当前注册请求是一个Replication请求,那么该注册请求不会被再次Replicate到下一个peer节点中。我们进入到关键的replicateToPeers()方法中看看为什么不会被同步:

private void replicateToPeers(Action action, String appName, String id,
                                  InstanceInfo info /* optional */,
                                  InstanceStatus newStatus /* optional */, boolean isReplication) {
        Stopwatch tracer = action.getTimer().start();
        try {
            // ... ...

            // If it is a replication already, do not replicate again as this will create a poison replication
            // 如果 isReplication 为true, 即当前是个同步注册信息的请求
            // 这里就直接返回了
            if (peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
                return;
            }

            // 向自己的peer节点同步注册信息
            for (final PeerEurekaNode node : peerEurekaNodes.getPeerEurekaNodes()) {
                // If the url represents this host, do not replicate to yourself.
                if (peerEurekaNodes.isThisMyUrl(node.getServiceUrl())) {
                    continue;
                }
                replicateInstanceActionsToPeers(action, appName, id, info, newStatus, node);
            }
        } finally {
            tracer.stop();
        }
    }

可以看到下面的代码

if (peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
    return;
}

就是Eureka不进行二次Replication的原因,如果当前请求是从其他Eureka发来的同步请求,那么该方法就直接返回了,不再执行后面的同步逻辑。

结论

通过上面的追踪我们确认了Eureka不进行二次同步是作者有意而为之,并不是bug。但是官方wiki上并没有明确写明这一点,文档并不太完善。可以考虑提一个Issue提醒一下开发组。

避开内存陷阱:手把手教你用RKNN零拷贝接口正确管理输入输出Tensor 本文深入解析RKNN零拷贝接口在边缘计算中的高效内存管理策略,通过YOLOX实例演示如何避免内存对齐错误和数据错位。详细介绍了`rknn_tensor_mem`系列API的正确使用方法,包括内存创建、绑定、释放全流程,以及性能优化技巧如内存池技术和多核NPU负载均衡,帮助开发者提升推理效率并避开常见陷阱。 阅读详情

相关推荐

基于单片机智能家居控制系统设计

*单片机设计介绍,基于单片机智能家居控制系统设计。

QQ2193276455的博客 1714

Eureka源码中isReplication的业务含义是什么

官方注释是这样的: true if this is a replication event from other replica nodes, false otherwise. isReplication = true 代表这个请求是同步请求,指的是Eureka Server集群之间的数据同步。 isReplication = false 代表这个请求是注册请求,指的是Eureka Client发起的服务注册请求。 EurekaHttpClient.class代表的是Eureka Cli..

reggergdsg的博客 900

Excel数字变成了小数点+E+17?这些方法帮你解决!

本文介绍了三种解决Excel中数字变成小数点+E+17问题的方法:通过下拉箭头或右键菜单设置单元格格式为文本、使用TEXT函数将科学计数法转换为文本。这些方法各有优缺点,适用于不同的场景和需求。在实际应用中,我们可以根据具体情况选择合适的方法来解决问题。通过以上方法,我们可以轻松地从繁琐的小数点+E+17问题中解脱出来,更便捷地处理Excel中的数字。希望本文能够帮助到您,让您在使用Excel时更加得心应手!

nntxthml的博客 1242

spring cloud:eureka源码之我见(十)eureka server集群机制

一、注册表同步及高可用 eureka server集群之间数据同步以及高可用都是通过这个机制实现的,现在我们来剖析一下这个机制的原理。 (1)我们知道,eureka server的初始化是在eureka-core的EurekaBootStrap中完成的,在其中完成了PeerEurekaNodes的初始化。且在接下来的代码中会调用PeerEurekaNodes的start方法。在该方法中,eureka server会解析配置文件中其他eureka server的url,并且基于url地址构造PeerEur

weixin_41703510的博客 346

电流互感器的使用分析

有关电流互感器使用的注意事项,回头再看,耳目一新。

qq_46757048的博客 2万+

Loupe Browser实战指南:解锁10xGenomics单细胞数据的可视化奥秘

本文提供了Loupe Browser的实战指南,帮助用户无需编程即可探索和可视化10xGenomics单细胞数据。文章详细介绍了从数据导入、界面导航到细胞亚群鉴定、差异基因分析的核心操作流程,并分享了高级技巧与避坑指南,是快速上手这一强大可视化工具的必备参考。

weixin_29313423的博客 206

Eureka(五) Eurka源码分析之 Eureka Server源码分析

EurekaServerAutoConfiguration是通过配置文件注册(@Bean)。EurekaServer 是服务的注册中心,负责Eureka Client的相关信息注册,主要职责 服务注册 接受心跳服务 服务剔除: 由eurekaServer主动剔除 心跳超时的服务 服务下线: 由 eurekaClient主动发送下线通知后,由eurekaServer接收后,删除服务 集群同步 首先找到 spring-cloud-netflix-eureka-server.xxx.jar下MET...

ForestCat的专栏 1950

一个响应ping包延迟偏大的问题

前段时间客户反馈一个使用pc上的命令行ping无线设备(WiFi4)时,设备平均响应时间(测试时长2小时,1秒Ping一次)相比其它机型偏慢的问题,并上传上具体的时间的Log.从log中看到,大多数包的响应还是比较快的,只是个别响应时间较长,且响应时间长的包时间几乎都是一样的100多ms.如下是部分响应时间截图. 整个2小时的测试时间里,总是时不时的出这么上102,104ms的响应时间,这直接导致了平均响应时间被拉大.于是本地测试,也发现了类似的延迟.本地测试时,现象略有...

流风回雪的博客 1万+

Eureka集群,事件监听解决方案

问题:Eureka集群后监听事件会推送多次,比如说你集群配置了3个地址,这样服务注册事件就会推送3次解决方案:    /* * 服务注册事件 */ @EventListener public void listen(EurekaInstanceRegisteredEvent event) { //处理Eureka集群监听多次问题 if(!event.isReplication()...

涛哥是个大帅比 2048

YOLOv8与注意力机制融合:EMA(高效多维注意力)的原理剖析与实战应用

本文介绍了如何在YOLOv8目标检测模型中集成EMA(高效多尺度注意力)机制。主要内容包括:EMA注意力机制的工作原理解析,展示其多尺度特征融合和高效计算特性;详细的环境配置与依赖安装指南;EMA模块的完整代码实现,包含分组处理、空间注意力权重计算和特征融合等关键步骤;以及将EMA集成到YOLOv8网络结构的方法。通过添加EMA模块,可以提升模型对关键特征的关注能力,有效抑制背景干扰,从而增强目标检测性能。本教程提供了从原理到实现的完整解决方案。

m0_64661770的博客 146

【从零开始学习 UVM】1.2、UVM 概述 —— UVM Installation(UVM 安装)

【从零开始学习 UVM】1.2、UVM 概述 —— UVM Installation(UVM 安装)

努力,加油每一天鸭~ 1943

Spring Cloud - Eureka 多节点 高可用部署 及 unavailable-replicas 问题

Eureka Server除了单点运行之外,还可以通过运行多个实例,并进行互相注册的方式来实现高可用的部署。所以我们只需要将Eureke Server配置其他可用的 serviceUrl 就能实现高可用部署。 将 application.yml 文件复制三分:application-9001.yml,application-9002.yml,application-9003.yml,分别添加配置项如下: application-9001.yml spring: application: nam

Sirius的博客 467

【AUTOSAR-RTE】-1-聊一聊RTE(Run-Time Environment)

RTE(Run-Time Environment)是AUTOSAR ECU架构的核心。

「汽车电子助手」的博客 6500

Eureka源码分析 封装源码api boolean 值 isReplication作用 二次Replication 等记录

一.Eureka源码分析-Eureka的核心类: 1.InstanceInfo.java(主要的记录实例的基础信息com.netflix.appinfo.InstanceInfo.java) 2.LeaseInfo.java(记录服务实例的租约信息com.netflix.appinfo.LeaseInfo.java) 3.LeaseManager.java(定义服务中心的一般操作接口com.netflix.eureka.lease.LeaseManager.java) public interfa

witty的博客 551

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Eureka Server源码分析一——走进Eureka 注册中心

走进Eureka 注册中心1、简介2、源码分析2.1 开启自动配置2.2 注册操作初步分析2.3 与Eureka对接2.3.1 Eureka侧PeerAwareInstanceRegistry注入2.3.2 Spring侧PeerAwareInstanceRegistry注入2.3.3 initEurekaServerContext方法调用3、运行注册中心 1、简介 Eureka Server,也称为服务注册中心。通过接收Eureka Client发送的注册请求,保存客户端注册信息。同时,将超时未接收到续约

weixin_46053046的博客 239

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Eureka-server源码分析

作者:陈刚,叩丁狼高级讲师。本文为原创文章,转载请注明出处。     我们在分析eureka-client的时候发现他是通过Http Rest 的方式做请求的,那么eureka-server一定是基于Rest风格 类似SpringMvc一样的模式接受处理请求。在 EurekaServerAutoConfiguration 自动配置类中有一个 jerseyFilterRegistration方法,...

wolfcode_cn的博客 799

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

eureka服务端源码分析

服务端主要功能 服务的注册 服务的续约 服务的下线 给客户端提供服务信息 这里不对每一点就讲解,就讲一下服务的注册。 如果看过eureka客户端的代码,可以知道,eureka客户端是通过发送http请求向服务端注册信息的,这里来看一下入口代码: /** * Registers information about a particular instance for an ...

tomorrow_fine的博客 411

eureka服务注册源码分析

eureka客户端启动是调用com.netflix.eureka.resources.ApplicationResource#addInstance函数进行服务注册. @POST @Consumes({"application/json", "application/xml"}) public Response addInstance(InstanceInfo info...

xiaolinzai888的专栏 427

Eureka Server启动源码分析(2)

Eureka启动源码分析 我们从@EnableEurekaServer注解开始分析 1.Eureka Server启动分析 1.1找到@EnableEurekaServer的实现类 EurekaServerAutoConfiguration 1.2分析EurekaServerInitializerConfiguration(eureka配置的加载类) //标识为配置文件 @Configuratio...

plumblum的博客 1016

springcloud 之 eureka 源码解析(6)-EurekaClient心跳、续约源码分析

springcloud 之 eureka 源码解析(6)-EurekaClient心跳、续约源码分析

yeyinzhu3211的专栏 440

【SpringCloud技术专题】「Eureka源码分析」从源码层面让你认识Eureka工作流程和运作机制(下)

承接上文的对应的Eureka的上篇介绍,我们开始介绍,详见 [【SpringCloud技术专题】「Eureka源码分析」从源码层面让你认识Eureka工作流程和运作机制(上)]

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。 395

Eureka服务续约(Renew)源码分析

主要对Eureka的Renew(服务续约),从服务提供者发起续约请求开始分析,通过阅读源码和画时序图的方式,展示Eureka服务续约的整个生命周期。服务续约主要是把服务续约的信息更新到自身的Eureka Server中,然后再同步到其它Eureka Server中。 Renew(服务续约)操作由Service Provider定期调用,类似于heartbeat。目的是隔一段时间Servic...

weixin_30666753的博客 372
上一篇: 使用Spring Cloud Security OAuth2搭建授权服务
下一篇: Spring Cloud Netflix Eureka: 多网卡环境下Eureka服务注册IP选择问题
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值