springcloud学习笔记之Ribbon组件(含项目)

本文是关于Spring Cloud Ribbon的学习笔记,详细介绍了Ribbon作为客户端负载均衡器的工作原理,包括与RestTemplate的结合使用、源码分析,以及Ribbon的核心组件如ILoadBalancer、LoadBalancerClient的实现。通过分析@LoadBalanced注解的作用和LoadBalancerInterceptor的拦截逻辑,揭示了Ribbon如何实现实现负载均衡请求。同时,文章探讨了Ribbon的负载策略,如随机、轮询、权重等,并解析了Ribbon与Eureka整合时的动态服务发现和健康检查机制。
摘要由CSDN通过智能技术生成

目录

一、Ribbon简介        

二、Ribbon与RestTemplate结合使用

三、Ribbon源码分析

   0、问题释疑

  1、@LoadBalanced原理探究

   1.1、LoadBalancerAutoConfiguration原理分析                 

  1.2、LoadBalancerInterceptor分析

  2、核心类LoadBlancedClient 接口以及其实现类

 2.1、LoadBlancedClient接口

2.2、RibbonLoadBalancerClient

     2.2.1  RibbonLoadBalancerClient简述

     2.2.2、  execute() 方法

     2.2.3、reconstructURI() 方法

3、ILoadBalancer 相关详解

   3.1、ILoadBalancer类

3.2、ILoadBalancer家族

      3.2.1、ILoadBalancer

      3.2.2、AbstractLoadBalancer

      3.2.3、BaseLoadBalancer

      3.2.4、DynamicServerListLoadBalancer


一、Ribbon简介        

Ribbon是Netflix公司开源的一个负载均衡的项目,相比于nginx 进程(应用)级别的负载均衡器,Ribbon是一个客户端负载均衡器(即通过编码的形式将负载功能内嵌到代码中),运行在客户端上。 Feign默认集成了Ribbon。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。在Spring Cloud中,当Ribbon与Eureka、Nacos等配合使用时,Ribbon可自动从注册中心获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。展示了Ribbon与Eureka配合使用时的架构


 

负载均衡

   RandomRule 随机

   RoundRobinRule 随机轮询

   BestAvailableRule  获取空闲服务实例

   WeightedResponseTimeRule 权重的形式挑选服务

   RetryRule 重试规则 在RoundRobinRule 的基础上等


多协议(HTTP,TCP,UDP)支持异步和反应模型
缓存

   默认从注册中心 中获取服务节点,但是如果注册中心的服务节点不可用则使用Ribbon缓存机制来获取服务

Ribbon中的关键组件

  • ServerList:可以响应客户端的特定服务的服务器列表。
  • ServerListFilter:可以动态获得的具有所需特征的候选服务器列表的过滤器。
  • ServerListUpdater:用于执行动态服务器列表更新。
  • Rule:负载均衡策略,用于确定从服务器列表返回哪个服务器。
  • Ping:客户端用于快速检查服务器当时是否处于活动状态。
  • LoadBalancer:负载均衡器,负责负载均衡调度的管理。

二、Ribbon与RestTemplate结合使用

       笔者有关ribbon组件使用的github地址

         前提准备启动多个服务和,这里通不过配置实例化RestTemplate(带有负载功能的)


@Configuration
public class RestConfig {

    @Bean
    //使用该注解为RestTemplate添加了负载均衡
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在使用该RestTemplate对象的类上注入即可

@Service
public class RibbonService {
    @Autowired
    private RestTemplate restTemplate;

    public String hi(String name){

        //这里的服务路径是 我们在eureka注册中心设置的服务名,该服务名下有多个服务实例,
        //每次基于负载规则来获取实力信息
        return restTemplate.getForObject("http://service-another/hi?name="+name,String.class);
    }

}

 服务注册列表

在注册中心中可以看到一个服务对应多个服务实例,图中圈中的部分是我们进行负载均衡的服务实例

 结果:  多次访问多实例的微服务,默认使用轮询来获取两个服务其中之一来提供服务。

三、Ribbon源码分析

   0、问题释疑

           在本篇博文中,我们源码的分析始终围绕两个核心疑问来进行展开

  • why 使用@LoadBalanced 修饰RestTemplate 就使得RestTemplate对象执行http请求(请求基于服务名)具备了负载请求的能力。

  • 哪个组件帮我们实现了真正的负载均衡的功能,怎们实现的

  1、@LoadBalanced原理探究

         看到项目二的服务,我们不禁有疑问,为什么使用@LoadBalanced 注解 服务的调用就有了负载请求的能力,这里我们需要关注一下LoadBalancerAutoConfiguration类(补充:Ribbon之所以能够实现负载 是因为LoadBlancedClient 该类是Ribbon实现负载均衡的核心接口,这里读者先不用纠结这个类 ,该接口及其实现类会在后面说明,)

   1.1、LoadBalancerAutoConfiguration原理分析                 

 //被该@Configuration注解 springBoot启动后进行自动化的配置
    @Configuration
    //根据条件判断是否触发自动化配置
    @ConditionalOnClass(RestTemplate.class)
    @ConditionalOnBean(LoadBalancerClient.class)
    //获取到配置相关的
    @EnableConfigurationProperties(LoadBalancerRetryProperties.class)
    public class LoadBalancerAutoConfiguration {

        //维护一份使用@LoadBalanced修饰的RestTemplate 列表对象
        @LoadBalanced
        @Autowired(required = false)
        private List<RestTemplate> restTemplates = Collections.emptyList();


        //RestTemplateCustomizer 为RestTemplate 添加LoadBalancerInterceptor拦截器的
        @Bean
        public SmartInitializingSingleton loadBalancedRestTemplateInitializer(
                final List<RestTemplateCustomizer> customizers) {
            return new SmartInitializingSingleton() {
                @Override
                public void afterSingletonsInstantiated() {
                    for (RestTemplate restTemplate : 
            LoadBalancerAutoConfiguration.this.restTemplates) {
                        for (RestTemplateCustomizer customizer : customizers) {
                            customizer.customize(restTemplate);
                        }
                    }
                }
            };
        }

        @Configuration
        @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
        static class LoadBalancerInterceptorConfig {
            
            //创建拦截器
            @Bean
            public LoadBalancerInterceptor ribbonInterceptor(
                    LoadBalancerClient loadBalancerClient,
                    LoadBalancerRequestFactory requestFactory) {
                return new LoadBalancerInterceptor(loadBalancerClient,
                               requestFactory);
            }

            //将拦截器LoadBalancerInterceptor 添加到restTemplate
            @Bean
            @ConditionalOnMissingBean
            public RestTemplateCustomizer restTemplateCustomizer(
                    final LoadBalancerInterceptor loadBalancerInterceptor) {
                return new RestTemplateCustomizer() {
                    @Override
                    public void customize(RestTemplate restTemplate) {
                        List<ClientHttpRequestInterceptor> list = new ArrayList<>
                         (restTemplate.getInterceptors());
                        list.add(loadBalancerInterceptor);
                        restTemplate.setInterceptors(list);
                    }
                };
            }
        }
}
  •   Ribbon要实现负载均衡自动化配置需要满足如下两个条件:

        @ConditionalOnClass(RestTemplate.class):RestTemplate类必须存在于当前工程的环境中。
        @ConditionalOnBean(LoadBalancerClient.class):在spring的Bean工程中必须有LoadBalancerClient.class的实现Bean。

  •      在自动化配置中主要做三件事:

        创建一个LoadBalancerInterceptor的Bean,用于实现对客户端发起请求时进行拦截,以实现客户端负载均衡。
        创建一个RestTemplateCustomizer的Bean,用于给RestTemplate增加LoadBalance

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值