SpringCloud组件Ribbon的IRule的问题排查

这篇具有很好参考价值的文章主要介绍了SpringCloud组件Ribbon的IRule的问题排查。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

实现思路如下:

  • 首先为特定节点打上标签
  • 通过截取请求中的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的。

原因梳理

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

由于服务节点在初始化的过程中,都是以服务名作为一个独立配置存在于容器中的:(如下图)
SpringCloud组件Ribbon的IRule的问题排查,问题排查,源码,后端,spring cloud,ribbon,IRule,负载均衡

用户服务单独有一套负载均衡规则(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持有的永远都是最后一个服务的服务列表。

大意图就是这个样子:
SpringCloud组件Ribbon的IRule的问题排查,问题排查,源码,后端,spring cloud,ribbon,IRule,负载均衡

问题解决

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

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

此时每次获取都是一个新的对象,相互不在影响。同理你如果需要覆盖RibbonClientConfiguration配置类中的对象时,也需要避免使用单例模式去定义它!文章来源地址https://www.toymoban.com/news/detail-726555.html

到了这里,关于SpringCloud组件Ribbon的IRule的问题排查的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springcloud 中RestTemplate 是怎么和 ribbon整合,实现负载均衡的?源码分析

    RestTemplate 内置了一个 ClientHttpRequestInterceptor ,这个是一个拦截器操作,我们可以在请求的前后做一些事情。然后我们看一下这个类,这个类里面 有一个 intercept 方法。我们看下这个实现类,里面有一个 LoadBalancerInterceptor 实现类。 我们来看 LoadBalancerInterceptor 实现类。 然后我

    2024年02月09日
    浏览(40)
  • springcloud微服务架构(eureka、nacos、ribbon、feign、gateway等组件的详细介绍和使用)

    目录 一、微服务演变 1、单体架构(Monolithic Architecture) 2、分布式架构  3、微服务 4、 总结 5、微服务架构 5.1、 微服务技术对比 5.2、企业需求 二、spring cloud  springCloud与SpringBoot的版本兼容关系 1、服务拆分及远程调用 1.1、服务拆分 1.1.1、服务拆分注意事项 1.1.2、项目实战

    2024年02月08日
    浏览(42)
  • 详解SpringCloud微服务技术栈:强推!源码跟踪分析Ribbon负载均衡原理、Eureka服务部署

    👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:认识微服务、服务拆分与远程调用 📚订阅专栏:微服务技术全家桶 希望文章对你们有所帮助 服务提供者:一次业务中,被其它微服务调用的服务(提供接口给

    2024年01月18日
    浏览(43)
  • springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。 Eureka包含两个组件:Eureka Server和Eure

    2024年04月10日
    浏览(43)
  • 【SpringCloud】通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题

    在上文的基础上,通过压测的结果可以看出,使用DiscoveryManager下线服务之后进行压测是不会出现异常情况的,但唯一缺点就是下线服务的方式是取消注册与续约,之后并没有结束进程。也就 使得在调用api下线后的服务其实是还存在处理请求的能力的 。加之eureka三种级别的缓

    2024年02月05日
    浏览(45)
  • 记一次线上bug排查-----SpringCloud Gateway组件 请求头accept-encoding导致响应结果乱码

           基于公司的业务需求,在SpringCloud Gateway组件的基础上,写了一个转发服务,测试开发阶段运行正常,并实现初步使用。但三个月后,PostMan请求接口,返回异常,经排查,从日志中获取到转发响应的结果为乱码:        跟踪日志: 转发到目标接口,响应结果已乱码

    2024年02月04日
    浏览(49)
  • springcloud-alibaba五大核心组件-后端开发工程(脚手架)搭建

    Gitee仓库地址 点我 服务注册与发现: nacos 配置中心: nacos 服务远程调用: openfeign 微服务网关: gateway 服务限流降级熔断等: sentinel 实现的功能demo openfeign服务远程调用 sentinel限流测试 gateway网关调用2个微服务 nacos的服务注册与发现 软件架构(环境) jdk: 1.8 maven: 3.5.2 nacos: 注册中心

    2024年02月05日
    浏览(51)
  • 【SpringCloud】Ribbon负载均衡

    🏡浩泽学编程 :个人主页  🔥 推荐专栏 :《深入浅出SpringBoot》《java对AI的调用开发》               《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 在Eureka注册中心中我们在添加完@LoadBalanced注解,即可实现负载均衡功能,现在一起

    2024年04月17日
    浏览(37)
  • SpringCloud--Ribbon解析

    一、Spring Cloud Ribbon简介 Spring Cloud Ribbon是Spring Cloud生态系统中的一部分,是一套基于 Netflix Ribbon 实现的客户端负载均衡工具,由于Spring Cloud对其进行二次封装,可以将面向服务的Rest模板(RestTemplate)请求转换成客户端负载均衡的服务调用。且无需单独部署,只需要在项目中

    2024年02月20日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包