Ribbon组件介绍和浅刨析

简介

  Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。
  通过引入Ribbon实现了服务消费者的客户端负载均衡功能,其中,我们使用了非常有用的对象RestTemplate。该对象会使用Ribbon的自动化配置,同时通过配置@LoadBalanced还能够开启客户端负载均衡。
@Bean
@LoadBalanced //使用ribbon
public RestTemplate restTemplate() {
   RestTemplate restTemplate = new RestTemplate();
   return restTemplate;
}

Ribbon分析

从@LoadBalanced注解码的注释中,可以知道该注解用来给RestTemplate标记,以使用负载均衡的客户端(LoadBalancerClient)来配置它。

org.springframework.cloud.client.loadbalancer.LoadBalancerClient

 

 下载源码后看到

 

▪️为了给一些系统使用,创建一个带有真实host和port的URI。
▪️一些系统使用带有原服务名代替host的URI,比如http://myservice/path/to/service。
▪️该方法会从服务实例中取出host:port来替换这个服务名。

从该接口中,我们可以通过定义的抽象方法来了解到客户端负载均衡器中应具备的几种能力:

▪️ServiceInstance choose(String serviceId):父接口ServiceInstanceChooser的方法,根据传入的服务名serviceId,从负载均衡器中挑选一个对应服务的实例。

▪️ T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request):使用从负载均衡器中挑选出的服务实例来执行请求内容。

▪️URI reconstructURI(ServiceInstance instance, URI original):为系统构建一个合适的host:port形式的URI。在分布式系统中,我们使用逻辑上的服务名称作为host来构建URI(替代服务实例的host:port形式)进行请求,比如http://myservice/path/to/service。在该操作的定义中,前者ServiceInstance对象是带有host和port的具体服务实例,而后者URI对象则是使用逻辑服务名定义为host的URI,而返回的URI内容则是通过ServiceInstance的服务实例详情拼接host:port形式的请求地址。

  到这里,LoadBalancerClient还只是一个抽象的负载均衡器接口,所以我们还需要找到它的具体实现类进一步进行分析,通过查看Ribbon的源码,可以很容易地在org.springframework.cloud.netflix.ribbon包下找到对应的实现类RibbonLoadBalancerClient

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

  

 

 此类实现了接口并作了具体逻辑处理。

然后在与LoadBalancerClient类同包下发现了自动配置类

org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration

为实现客户端负载均衡器的自动化配置类LoadBalancerAutoConfiguration

从LoadBalancerAutoConfiguration类上的注解可知,Ribbon实现负载均衡自动化配置需要满足下面两个条件:

▪️@ConditionalOnClass(RestTemplate.class):RestTemplate必须存在于当前工程的环境中。

▪️@ConditionalOnBean(LoadBalancerClient.class):在Spring的Bean工程中必须有LoadBalancerClient的实现bean。

该自动配置类,主要做了下面三件事:

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

        创建了一个RestTemplateCustomizer的Bean,用于给RestTemplate增加LoadbalancerInterceptor

        维护了一个被@LoadBalanced注解修饰的RestTemplate对象列表,并在这里进行初始化,通过调用RestTemplateCustomizer的实例来给需要客户端负载均衡的RestTemplate增加LoadBalancerInterceptor拦截器。

当一个被@LoadBalanced注解修饰的RestTemplate对象向外发起HTTP请求时,会被LoadBalancerInterceptor类的intercept函数所拦截。由于我们在使用RestTemplate时候采用了服务名作为host,所以直接从HttpRequest的URI对象中通过getHost()就可以拿到服务名,然后调用execute函数去根据服务名来选择实例并发起实际的请求。

负载均衡器

 

Ping:在BaseLoadBalancer的默认构造函数中,会直接启动一个用于定时检查server是否健康的任务。该任务默认的执行间隔为:10秒。

ServerList: 服务列表(总)

ServerListUpdater: 服务更新时最新到达的地方

ServerListFilter:接口非常简单,该接口中定义了一个方法List getFilteredListOfServers(List servers),主要用于实现对服务实例列表的过滤,通过传入的服务实例清单,根据一些规则返回过滤后的服务实例清单。

Rule --> IRule: 负载策略接口

本片简略刨析,详解转到  https://www.jianshu.com/p/1bd66db5dc46
posted @ 2020-10-20 17:14  一半人生  阅读(286)  评论(0编辑  收藏  举报