iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >SpringCloud负载均衡组件Ribbon源码分析
  • 756
分享到

SpringCloud负载均衡组件Ribbon源码分析

2023-07-02 18:07:48 756人浏览 安东尼
摘要

本文小编为大家详细介绍“SpringCloud负载均衡组件Ribbon源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“springCloud负载均衡组件Ribbon源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来

本文小编为大家详细介绍“SpringCloud负载均衡组件Ribbon源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“springCloud负载均衡组件Ribbon源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    项目实战

    创建项目

    同样的,我们的项目现在依然有一个reGIStry注册中心,一个provider服务提供者,接下来,我们再次修改一下consumer服务消费者的代码:

    @EnableEurekaClient@SpringBootApplication@RestControllerpublic class ConsumerApplication {    public static void main(String[] args) {        SpringApplication.run(ConsumerApplication.class, args);    }    @Bean    @LoadBalanced    RestTemplate restTemplate() {        return new RestTemplate();    }    @Autowired    DiscoveryClient discoveryClient;    @Autowired    RestTemplate restTemplate;    @GetMapping("/hello2")    public String hello2(String name) {        String returnInfo = restTemplate.getForObject(  "Http://provider/hello?name={1}", String.class, name);        return returnInfo;    }}

    在这个版本,同样的,还是创建RestTemplate Bean对象,不同的是上面仅仅增加了@LoadBalanced注解。

    启动项目验证

    SpringCloud负载均衡组件Ribbon源码分析

    依然正确返回了结果!

    太神奇了吧,比我们自己开发的负载均衡组件简单太多了吧,仅仅在restTemplate() 方法上面增加了一个@LoadBalanced注解,怎么就实现的呢?废话不说,为了一探究竟,扒一扒源码吧!

    源码分析

    首先,点击@LoadBalanced注解进去,没有什么特别之处,那么我们在想想,Spring在创建Bean实例的时候,注解在什么地方起了作用?什么?不知道?翻一下这篇文章吧:

    肝了两周,一张图解Spring核心源码

    通过回顾Spring启动以及Bean的生命周期创建过程,我们就会发现加上@LoadBalancer注解后,项目启动时就会加载LoadBalancerAutoConfiguration这个配置类(通过spring-cloud-commons包下面的的spring.factories)。通过查看该配置类源码,发现其有个静态内部类LoadBalancerInterceptorConfig,其内部又创建了一个负载均衡拦截器:LoadBalancerInterceptor,该拦截器包含有一个loadBalancerClient参数:

    @ConditionalOnMissinGClass({"org.springframework.retry.support.RetryTemplate"})    static class LoadBalancerInterceptorConfig {        LoadBalancerInterceptorConfig() {        }        @Bean        public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {            return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);        }        @Bean        @ConditionalOnMissingBean        public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {            return (restTemplate) -> {                List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());                list.add(loadBalancerInterceptor);                restTemplate.setInterceptors(list);            };        }    }

    我们继续点击LoadBalancerInterceptor类进入,发现intercept方法,该方法中调用了LoadBalancerClient的execute方法,

        public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {        URI originalUri = request.getURI();        String serviceName = originalUri.getHost();        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);        return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));    }

    LoadBalancerClient是一个接口,点击进去我们发现其实现类是RibbonLoadBalancerClient,查看其继承关系:

    SpringCloud负载均衡组件Ribbon源码分析

    通过接口中的方法名称,我们可以猜想,choose方法就是选择其中服务列表中其中一个服务,reconstructURI方法就是重新构造请求的URI。

    选择服务

    choose方法是在RibbonLoadBalancerClient实现类中实现的

        public ServiceInstance choose(String serviceId, Object hint) {        Server server = this.getServer(this.getLoadBalancer(serviceId), hint);        return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));    }

    在这个方法中,先调用 getServer 方法获取服务,这个方法最终会调用 ILoadBalancer 接口的 chooseServer 方法,而 ILoadBalancer 接口的实现类默认是ZoneAwareLoadBalancer。

    ZoneAwareLoadBalancer 继承自 DynamicServerListLoadBalancer ,而在 DynamicServerListLoadBalancer 的构造方法中,调用了 this.restOfInit(clientConfig);在restOfInit这个方法中,通过 this.updateListOfServers()来获取服务列表;

    而在chooseServer ()方法中,就会根据负载均衡算法,选择其中一个服务并返回:

     BaseLoadBalancer zoneLoadBalancer = this.getLoadBalancer(zone); server = zoneLoadBalancer.chooseServer(key);

    地址替换

    选择其中一个服务信息后,怎么将接口从 http://provider/hello 变为 http://localhost:8003/hello 呢?还记得上面我们说的reconstructURI方法吗?通过配置类LoadBalancerAutoConfiguration加载后,会注入LoadBalancerInterceptor拦截器,该拦截器会拦截我们的请求,并对请求地址进行处理,重构方法的具体实现在 LoadBalancerContext 类的 reconstructURIWithServer 方法中

    public URI reconstructURIWithServer(Server server, URI original) {        String host = server.getHost();        int port = server.getPort();        String scheme = server.getScheme();        if (host.equals(original.getHost()) && port == original.getPort() && scheme == original.getScheme()) {            return original;        } else {            if (scheme == null) {                scheme = original.getScheme();            }            if (scheme == null) {                scheme = (String)this.deriveSchemeAndPortFromPartialUri(original).first();            }            try {                StringBuilder sb = new StringBuilder();                sb.append(scheme).append("://");                if (!Strings.isNullOrEmpty(original.getRawUserInfo())) {                    sb.append(original.getRawUserInfo()).append("@");                }                sb.append(host);                if (port >= 0) {                    sb.append(":").append(port);                }                sb.append(original.getRawPath());                if (!Strings.isNullOrEmpty(original.getRawQuery())) {                    sb.append("?").append(original.getRawQuery());                }                if (!Strings.isNullOrEmpty(original.getRawFragment())) {                    sb.append("#").append(original.getRawFragment());                }                URI newURI = new URI(sb.toString());                return newURI;            } catch (URISyntaxException var8) {                throw new RuntimeException(var8);            }        }    }

    可以看到该方法中,将原始的请求地址original,替换成了选取的服务的IP和端口。并最终调用该服务的接口方法。

    读到这里,这篇“SpringCloud负载均衡组件Ribbon源码分析”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

    --结束END--

    本文标题: SpringCloud负载均衡组件Ribbon源码分析

    本文链接: https://www.lsjlt.com/news/343747.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • SpringCloud负载均衡组件Ribbon源码分析
      本文小编为大家详细介绍“SpringCloud负载均衡组件Ribbon源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringCloud负载均衡组件Ribbon源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
      99+
      2023-07-02
    • SpringCloud超详细讲解负载均衡组件Ribbon源码
      目录前言项目实战创建项目启动项目验证源码分析选择服务地址替换总结前言 上一篇文章中我们通过自己开发了一个负载均衡组件,实现了随机算法的负载均衡功能,如果要实现其他算法,还需要修改代码...
      99+
      2024-04-02
    • SpringCloud Ribbon负载均衡原理
      目录一、Ribbon负载均衡原理1 负载均衡原理2 负载均衡策略(IRule接口)3 Ribbon默认懒加载4 总结:Ribbon负载均衡规则、自定义、饥饿加载一、Ribbon负载均...
      99+
      2024-04-02
    • SpringCloud客户端负载均衡——Ribbon
        Ribbon——A ribbon is a long, narrow piece of cloth that you use for tying things together or as a decoration.  Ribbon是一...
      99+
      2023-06-02
    • SpringCloud怎么实现Ribbon负载均衡
      这篇文章主要讲解了“SpringCloud怎么实现Ribbon负载均衡”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringCloud怎么实现Ribbon负载均衡”吧!Ribbon使用R...
      99+
      2023-06-30
    • Spring Cloud负载均衡组件Ribbon原理解析
      目录前言一个问题引发的思考Ribbon的简单使用Ribbon 原理分析LoadBalancerAutoConfiguration 自动装配RestTemplateCustomizer...
      99+
      2024-04-02
    • springcloud集成ribbon负载均衡的实例代码
      本文比较简单集成ribbon,如需要更详细,请查看我的更多博客内容。 首先创建两个服务提供者 服务一,集成的nacos注册中心,这块随便写一个同名接口 端口配置8301 服务二...
      99+
      2024-04-02
    • 深入理解Java SpringCloud Ribbon 负载均衡
      目录前言1、抛出问题2、源码解析2.1、LoadBalancerIntercepor2.2、LoadBalancerClient2.3、负载均衡策略IRule2.4、总结3、负载均衡...
      99+
      2024-04-02
    • SpringCloud Ribbon中的7种负载均衡策略
      SpringCloud Ribbon中的7种负载均衡策略 Ribbon 介绍负载均衡设置7种负载均衡策略1.轮询策略2.权重策略3.随机策略4.最小连接数策略5.重试策略6.可用性敏感策略7....
      99+
      2023-09-07
      spring cloud ribbon 负载均衡
    • SpringCloud笔记(Hoxton)Netflix之Ribbon负载均衡示例代码
      目录Ribbon使用负载均衡代码示例注册中心Provider接口实现Consumer添加依赖测试Ribbon使用 Ribbon是管理HTTP和TCP服务客户端的负载均衡器,Ribbo...
      99+
      2024-04-02
    • SpringCloud中如何利用Ribbon实现负载均衡
      SpringCloud中如何利用Ribbon实现负载均衡,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。首先在pom文件添加Fegin的依赖包。  <d...
      99+
      2023-06-05
    • SpringCloud Ribbon负载均衡使用策略是什么
      这篇“SpringCloud Ribbon负载均衡使用策略是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Sp...
      99+
      2023-07-05
    • SpringCloud 客户端Ribbon负载均衡的实现方法
      目录Ribbon 介绍开启客户端负载均衡,简化 RestTemplate 调用负载均衡策略饥饿加载Ribbon 介绍 Ribbon 是 Netflix 提供的一个基于 Http 和 ...
      99+
      2024-04-02
    • SpringCloud 2020-Ribbon负载均衡服务调用的实现
      目录1、概述2、Ribbon负载均衡演示3、Ribbon核心组件IRule4、Ribbon负载均衡算法4.1 原理 + 源码4.2 手写负载均衡算法1、概述 官网:https://...
      99+
      2024-04-02
    • Spring Cloud负载均衡组件Ribbon原理是什么
      这篇文章主要介绍“Spring Cloud负载均衡组件Ribbon原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring Cloud负载均衡组件Ribbon原理是什...
      99+
      2023-06-30
    • SpringCloud LoadBalancerClient 负载均衡原理解析
      目录深入解析 LoadBalancerClient 接口源码:1、LoadBalancerClient 源码解析:2、ILoadBalancer 源码解析:  &...
      99+
      2024-04-02
    • springcloud中Ribbon和RestTemplate实现服务调用与负载均衡
      文件目录结构 文件目录结构很重要,特别注意的是rule文件要放在主启动类上一级位置,才能够扫描。 写pom <dependencies> <!...
      99+
      2024-04-02
    • 深入浅析spring cloud中的Ribbon负载均衡
      这期内容当中小编将会给大家带来有关深入浅析spring cloud中的Ribbon负载均衡,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、负载均衡负载均衡(Load Balance): 建立在现有网络结...
      99+
      2023-05-31
      spring cloud ribbon 负载均衡
    • Kubernetes gRPC负载均衡分析
      本篇内容主要讲解“Kubernetes gRPC负载均衡分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Kubernetes gRPC负载均衡分析”吧!安装环境依赖docker-desktop...
      99+
      2023-06-25
    • SpringCloud Gateway详细分析实现负载均衡与熔断和限流
      目录环境准备1.pom依赖2.yaml配置3.路由转发和负载均衡测试user服务暴露接口返回结果输出4.gateway熔断实现4.1 熔断代码4.2 测试5.gateway限流5.1...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作