SpringCloud组件Ribbon的IRule的问题排查

news2024/11/18 20:16:34

最近很久没有写文章啦,刚好遇到了一个问题,其实问题也挺简单,但是还是得对源码有一定了解才能够发现。

最近在实现一个根据请求流量的标签,将请求转发到对应的节点,其实和俗称的灰度请求有点相似,

实现思路如下:

  • 首先为特定节点打上标签
  • 通过截取请求中的header的标签key,然后存入上下文中
  • 在服务转发时(Feign),在负载均衡步骤前将节点的标签和请求标签相匹配,筛选出标签节点。
  • 将标签节点进行策略选择一个合适的节点然后转发。

场景定义

实现伪代码:

  1. 定义策略
public class MyRule extends AbstractLoadBalancerRule {
 
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
    @Override
    public Server choose(Object o) {
        return this.choose(this.getLoadBalancer(),o);
    }

    public Server choose(ILoadBalancer lb, Object key) {
       		// 标签匹配
       		// 节点选择
       		// 策略选举
            return server;
        }
    }
}
  1. 注入容器
@Configuration
public class MyRuleConfig {
    @Bean
    public IRule ribbonRule(){
        return new MyRule();
    }
}

好,一切准备就绪。

在应用当中很快就遇到了问题,在选择过程中,节点地址出现错乱。

明明请求的是A服务节点,结果转发的是B节点

通过调试发现ILoadBalancer对象有问题,比如A服务节点持有的节点列表竟然是B的节点列表。

ILoadBalancer: 每个服务都独立持有一个独属于该服务负载列表。比如A服务持有的就是A服务列表,B就是B的.但此时却出现了归属于A的ILoadBalancer中节点列表竟然都是B的。

原因梳理

最终排查发现就是注入的方式问题,为什么这么说呢?

由于服务节点在初始化的过程中,都是以服务名作为一个独立配置存在于容器中的:(如下图)
服务节点加载图

用户服务单独有一套负载均衡规则(IRule),同理order订单服务也是单独一套负载均衡规则,双方各自持有了各自的服务列表(ILoadBalancer)。

但是由于我们要改写IRule的实现,同时注入到容器中,让服务能够获取到我改写的实现,我们直接@Bean给加入了。

此时在初始化这个IRule的时候就会出现问题,因为IRule内部是持有ILoadBalancer的,但是ILoadBalancer针对每个服务都是不一样的。

我们看一下IRule是怎么被加载到用户服务上下文的:
com.netflix.loadbalancer.BaseLoadBalancer#setRule

public void setRule(IRule rule) {
    if (rule != null) { // 此时我们是从容器获取到的,默认是个单例
        this.rule = rule;
    } else {
        /* default rule */
        this.rule = new RoundRobinRule();
    }
    
    if (this.rule.getLoadBalancer() != this) { // 肯定满足
    	// 将自身交给rule
        this.rule.setLoadBalancer(this);
    }
}

别忘了,我们通过@Bean加入到容器中时,是单例的。问题也出在这!
就意味着,每次初始化的时候,在设置setLoadBalancer时,就是在单例的IRule基础上,从后往前覆盖,最终IRule持有的永远都是最后一个服务的服务列表。

大意图就是这个样子:
在这里插入图片描述

问题解决

那么我们如何解决这个问题呢?
我们知道了原因是由于单例导致的,那么我们就可以将自定义的策略改成多实例的注入。

@Configuration
public class MyRuleConfig {
    @Bean
    @Scope("prototype") // 将单例变为原型
    public IRule ribbonRule(){
        return new MyRule();
    }
}

此时每次获取都是一个新的对象,相互不在影响。同理你如果需要覆盖RibbonClientConfiguration配置类中的对象时,也需要避免使用单例模式去定义它!

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

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

相关文章

Redis安装教程

官网地址 地址链接:传送门 安装步骤 这里有更多版本的选择 进去根据自己的需要选择版本,我这里用的7系列的稳定版。

软件企业找第三方软件测评机构做确认测试有什么优势?

软件确认测试是一个在软件开发过程中十分重要的环节。它确保了软件的功能符合预期,达到了用户的需求和期望。确认测试主要验证软件的功能、性能、易用性、稳定性等方面,旨在发现和修复潜在的问题和缺陷。通过进行全面的确认测试,软件企业可以…

操作系统学习笔记--进程与线程

进程 概念 不同的角度有不同的定义 进程是程序的一次执行过程进程是一个程序及其数据在处理机上顺序执行时所发生的活动进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位 进程:是动态的,是…

Flink-SQL join 优化 -- MiniBatch + local-global

背景 问题1. 近期在开发flink-sql期间,发现数据在启动后,任务总是进行重试,运行一段时间后,container心跳超时,内存溢出,作业无法进行正常工作 023-10-07 14:53:30,408 | INFO | [flink-akka.actor.defa…

关于需要用到暂停的unity游戏

在做游戏的时候,我们经常需要用到Time.timescalse 0;来暂停游戏 但是,我们有些其他的东西,却不想它们被暂停影响了。 例如 1、Dotween 如上图增加一段.SetUpdate(true)即可 2、animator public Animator Ani;public void Firs…

链表(7.27)

3.3 链表的实现 3.3.1头插 原理图: newnode为新创建的节点 实现: //头插 //让新节点指向原来的头指针(节点),即新节点位于开头 newnode->next plist; //再让头指针(节点)指向新节点&#…

【亲测】简易商城小程序源码-易优CMS后台

易优小程序是基于前端开源小程序后端易优CMS标签化API接口, 是一套开源、快速搭建个性化需求的小程序CMS。轻量级TP底层框架,前后端分离, 标签化API接口可对接所有小程序,支持二次开发。即使小白用户也能轻松搭建制作一套完整的线…

90后整顿秦始皇老板

我的日常就像跑步机上急速前行的仓鼠,使劲往前冲,心有余力力有限。 我在一个电商运营公司做策划和写文案,每天总是加不完的班,从来没见过下午六点钟的太阳。 我做文案吗?唉,说实话,我倒觉得大…

C#(Csharp)我的基础教程(二)(我的菜鸟教程笔记)-属性和字段的探究与学习

目录 1、字段字段特点:2、属性属性的特点 1、字段 字段是定义在方法外面的变量,是成员变量,主要是为了类的内部数据交换使用,字段一般是用private修饰,也可以用readonly修饰,表示只读字段,其它…

10月底下架!亚马逊新增5大售前审核品类,提醒这6大站点卖家注意

近期,不少加拿大站、沙特阿拉伯站、埃及站、瑞典站、波兰站以及比利时站卖家陆续收到了亚马逊合规政策要求邮件,包括加拿大站对于“带拉绳的童装”、“水壶”、“玻璃门和围栏”三个品类,沙特阿拉伯、埃及对于“面向婴幼儿的食品”品类&#…

如何在C++项目中用C#运行程序调试C++ DLL

问题描述 在C#项目中调用C DLL时报错或者运行结果不符,此时需要运行C#项目并在C中加入断点进行调试 项目准备 项目一:C#项目(该项目调用C DLL)项目二:C项目(生成C DLL) 这两个项目不需要在同…

BGP服务器租用腾讯云和阿里云价格对比

BGP云服务器像阿里云和腾讯云均是BGP多线网络,速度更快延迟更低,阿里云BGP服务器2核2G3M带宽优惠价格108元一年起,腾讯云BGP服务器2核2G3M带宽95元一年起,阿腾云atengyun.com分享更多云服务器配置如2核4G、4核8G、8核16G等配置价格…

VALSE2023-快速总结

会议快速总结 1. 前言2. 热点词2.1 自监督预训练2.2 MIM(Masked Image Modeling)2.3 MAE(Masked Autoencoders)2.4 clip(Contrastive Language-Image Pre-Training)模型2.5 对比学习2.6 扩散模型(diffustion model)2.7 Nerf&#…

超高速PCIe实时运动控制卡与应用方案将亮相深圳NEPCON,正运动技术邀您前来体验!

助力电子半导体设备加速国产替代导入,正运动超高速PCIe运动控制卡可覆盖电子半导体大部分工艺流程应用,提供高速高精稳定的运动控制解决方案。 ■展会名称: NEPCON ASIA 2023亚洲电子生产设备暨微电子工业展(以下简称“2023亚洲…

c#设计模式-行为型模式 之 中介者模式

🚀简介 又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。 从下右图中可以看到,任何一个类的变 动,只会影响的类本身,以及…

TikTok震撼全球!用户来自何方?

TikTok(抖音国际版)作为一款风靡全球的短视频应用,正以惊人的速度改变着人们的娱乐方式、社交习惯和消费行为。它汇聚了来自不同地域、不同文化背景的用户,形成了一个庞大而多样化的社区。 这个社区的形成和发展,让我…

TikTok Shop:年轻一代购物革命的未来之旅

随着社交媒体的不断崛起,我们的生活方式也在发生深刻的变革。在这个数字化时代,年轻一代的文化和消费习惯正在不断演变,而TikTok Shop正是这场购物革命的先锋。 一、TikTok Shop的崛起 TikTok Shop是TikTok平台上的一项新功能,旨在…

Vue3中使用tinymce全功能演示,包括开源功能

效果图: 1、下载插件: npm i tinymce npm i tinymce/tinymce-vue 2、在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中 (可以先创建一个tinymce文件夹): 3、在tinymce官网中下载中文包,并放在刚…

天锐绿盾加密软件——企业数据防泄密-CAD图纸、文档、源代码加密管理系统@德人合科技

天锐绿盾是一款专门为企业提供数据防泄密和文档加密管理的软件。该软件通过加密技术保护企业的核心数据,防止数据泄露和侵权行为,同时提供了全方位的文档加密管理系统,实现了对企业数据的安全保障和有效管理。 PC访问地址: isite…