SpringCloud Netflix Ribbon源码解析(推荐)

SpringCloud Netflix Ribbon源码解析

首先会介绍Ribbon 相关的配置和实例的初始化过程,然后讲解Ribbon 是如何与OpenFeign 集成的,接着讲解负载均衡器LoadBalancerCli ent , 最后依次讲解ILoadB alancer的实现和负载均衡策略Rule 的实现。

配置和实例初始化

@RibbonClient 注解可以声明Ribbon 客户端,设置Ribbon 客户端的名称和配置类,configuration 属性可以指定@Configuration 的配置类,进行Ribbon 相关的配置。@RibbonClient还会导入( import ) RibbonClientConfigurationRegistrar 类来动态注册Ribbon 相关的BeanDefinition。
RibbonClientConfigurationRegistrar 是ImportBeanDefinitionRegistrar 的实现类,ImportBeanDefinitionRegistrar 是Spring 动态注册BeanDefinition 的接口, 可以用来注册Ribbon 所需的BeanD的iition , 比如说Ribbon客户端实例( Ribbon Client ) lmportBeanDefinitionRegistrar的registerBeanDefinitions 方法可以注册Ribbon 客户端的配置类, 也就是@RibbonClient 的configuration 属性值

与OpenFeign 的集成

FeignCJientFactoryBean 是创造FeignClient 的工厂
类,在其getObject 方法中有一个分支判断,当请求URL 不为空时, 就会生成一个具有负载均衡的FeignClient 。在这个过程中, OpenFeign 就默认引入了Ribbon 的负载均衡实现.

LoadBalancerFeignClient#execute 方法会将普通的Request 对象转化为RibbonRequest , 并使用FeignLoadBalancer 实例来发送RibbonRequest。execute 方法会首先将Request 的URL转化为对应的服务名称,然后构造出RibbonRequest 对象,接着调用lbClient 方法来生成FeignLoadBalancer 实例,最后调用FeignLoadBalancer 实例的executeWithLoadBalancer 方法来处理网络请求。

//LoadBalancerFeignClient java
public Response execute(Reqest reqi且est, Request .Options options) throws 工OException {
try {
// :负载均衡时, host 就是需要调用的服务的名称
URI asurn= URI . create(request.url()) ;
String clientName = asur. getHost();
URI ur 工WithoutHost = cleanUrl(reqi且est . url(), cl 工entName) ;
//构造RibbonRequest,delegate 一般就是真正发送网络请求的客户端,比如说OkHttpClient
和ApacheClient
Fe 工gnLoadBalancer . R 工bbonRequest ribbonRequest = new FeignLoadBalancer .
RibbonRequest(
this . delegate , re 守uest , ur 工WithoutHost) ;
IClientConfig requestConfig = getClientConfig(options, clientName) ;
//executeWithLoadBalancer是进行负载均衡的关键
return lbClient(clientName) . executeWithLoadBalancer(ribbonRequest ,
requestConfig) . toResponse () ;
catch (ClientException e) {
IOException io = findIOException(e) ;
if ( io ! = null) {
throw io;
throw new RuntimeException(e) ;
private FeignLoadBalancer lbCl 工ent(Str 工ng cl 工entName) {
//调用CachingSpringLoadBalancerFactory 类的create方法。
return this . lbClientFactory . create(clientName) ;

lbClientFactory 的参数是CachingSpringLoadBalancerFactory 的实例, 它是带有缓存机制的FeignLoadBalancer 的工厂类。

create 方法的clientName 参数是指HTTP 请求对应的服务端名称, 它会首先使用这个名称去缓存中查找是否已经存在对应的实例。如果没有, 再根据系统是否支持请求重试来创建出不同的F eignLoadBalancer 实例, 最后将该实例存储到缓存中.

FeignLoadBalancer 是OpenFeign 在不需要重试机制的情况下默认的负载均衡实现。它的execute 方法的实现很简单,使用RibbonRequest 对象的客户端来发送网络请求,然后
将Response 包装成RibbonResponse 进行返回。RibbonRequest 的request 方法返回的对象就是构造RibbonRequest 对象时传入的delegate 参数。该参数是Client 接口的实例, Client接口是OpenFeign 真正发送网络请求的客户端, 比如说OkHttpClient 和ApacheClient 。FeignLoadBalancer 的execute 方法如下所示:

//Fe i gnLoadBalancer. ] ava
public RibbonResponse execute(RibbonRequest request , IClientConfig configOverride)
throws IOException {
Request.Options options ;
if (configOverride ! = null) {
RibbonPropert 工es override = RibbonPropertes . from(configOverride);
options = new Request.Options(
else {
override . connectTimeout(th 工s . connect Timeout),
override . readTimeout(this . readT 工meout));
options = new Request . Options(th 工s.connectTimeout, this readTimeout);
Response response = request . client() . execute(request . toReqest(), options) ;
return new RibbonResponse(request . getUri() , response) ;

FeignLoadBalancer 是AbstractLoadBalancerAwareC!ient 的子类,其executeWithLoadBalance方法会首先创建一个LoadBalancerCommand 实例,然后在该实例的submit 方法的回调中调用子类的execute方法

其中, buildLoadB a lan cerCommand 方法使用了LoadBalancerCommand.Builder 来创建LoadBalancerCornmand 实例,并将AbstractLoadBalancerAwareC!ient 作LoadBalancerContext接口的实例设置给LoadBalancerCommand 实例

LoadBalancerContext 的getServerFromLoadBalancer 方法调用了ILoadBalancer 的chooseServer方法,从而完成了负载均衡中服务器的选择。

负载均衡器LoadBalancerClient

LoadBalancerClient是Ribbon 项目的核心类之一,可以在RestTemplate 发送网络请求时替代RestTemplate 进行网络调用

LoadBalancerClient 接口继承了ServicelnstanceChooser 接口,其choose 方法可以从服务器列表中依据负载均衡策略选出一个服务器实例

RibbonLoadBalancerClient 是LoadBalancerClient 的实现类之一, 它的execute 方法会首先使用ILoadBa lancer 来选择服务器实例( Server ),然后将该服务器实例封装成RibbonServer 对象, 最后再调用LoadBalancerRequest 的apply 方法进行网络请求的处理。

ILoadBalancer

ILoadBalancer 是Ribbon 的关键类之二, 它是定义负载均衡操作过程的接口。Ribbon通过SpringClientFactory 工厂类的getLoadBalancer 方法可以获取ILoadBalancer 实例。根据Ribbon 的组件实例化机制, ILoadBalnacer 实例是在RibbonAutoConfiguration 中被创建生成的。

SpringClientFactory 中的实例都是RibbonClientConfiguration 或者自定义C onfiguration配置类创建的Bean 实例。RibbonClientConfiguration 还创建了Rule 、IPing 和S e rver List
等相关组件的实例。使用者可以通过自定义配置类给出上述几个组件的不同实例。

负载均衡策略实现

lRule 是定义Ribbon 负载均衡策略的接口,你可以通过实现该接口来自定义自己的负载均衡策略, Ribbon ClientConfiguration 配置类则会给出!Rule 的默认实例,Rule 接口的choose 方法就是从一堆服务器中根据一定规则选出一个服务器。Rule 有很多默认的实现类,这些实现类根据不同的算法和逻辑来进行负载均衡。

在大多数情况下, 这些默认的实现类是可以满足需求的,如果有特殊需求,可以自己实现。Ribbon 内置的Rule 子类如下所示。

  • BestAvailableRule :选择最小请求数的服务器。
  • ClientConfigEnabledRoundRobinRule :使用RandomRobinRule 随机选择一个服务器。
  • RoundRobinRul e :以RandonRobin 方法轮询选择服务器。
  • RetryRule : 在选定的负载均衡策略上添加重试机制。
  • WeightedResponseTimeRule :根据响应时间去计算一个权重( we ight ) ,响应时间越
  • 长,权重越低,权重越低的服务器,被选择的可能性就越低。
  • ZoneAvoidanceRule :根据服务器所属的服务区的整体运行状况来轮询选择。

到此这篇关于SpringCloud Netflix Ribbon源码解析(推荐)的文章就介绍到这了,更多相关SpringCloud Netflix Ribbon源码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详细介绍SpringCloud之Ribbon

    一:Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等.简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器.我们也很容易使用Ribbon实现自定义的负载均衡算法. 二:LB方案分类 目前主流的LB方案可分成两类:一种是集中式LB,

  • 浅谈SpringCloud之zuul源码解析

    zuul各版本实现存在一些微小的变化,总的实现思想未改变,以spring-cloud-netflix-core-1.3.6.RELEASE为例 一.zuul的重要的初始化类 org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration org.springframework.cloud.netf

  • 详解SpringCloud Ribbon 负载均衡通过服务器名无法连接的神坑

    一,问题 采取eureka集群.客户端通过Ribbon调用服务,Ribbon端报下列异常 java.net.UnknownHostException: SERVICE-HI java.lang.IllegalStateException: No instances available for SERVICE-HI java.lang.IllegalStateException: Request URI does not contain a valid hostname: http://SERVI

  • SpringCloud Edgware.SR3版本中Ribbon的timeout设置方法

    概述 Spring Cloud中,客户端的负载均衡使用的是Ribbon,Ribbon的超时时间默认很短,需要进行调整. Spring Cloud版本 Edgware.SR3 Ribbon timeout设置 Ribbon的默认timeout时间是1秒,这个可以在RibbonClientConfiguration类中看到. public class RibbonClientConfiguration { public static final int DEFAULT_CONNECT_TIMEOUT

  • SpringCloud 中使用 Ribbon的方法详解

    在前两章已经给大家讲解了Ribbon负载均衡的规则 以及 如何搭建Ribbon并调用服务,那么在这一章呢 将会给大家说一说如何在SpringCloud中去使用Ribbon.在搭建之前 我们需要做一些准备工作. 1. 搭建Eureka服务器:springCloud-ribbon-server(项目名称) 2. 服务提供者:springCloud-ribbon-police(项目名称) 3. 服务调用者:springCloud-ribbon-person(项目名称) 搭建Eureka服务器 配置 p

  • SpringCloud Ribbon 负载均衡的实现

    前言 Ribbon是一个客户端负载均衡器,它提供了对HTTP和TCP客户端的行为的大量控制.我们在上篇(猛戳:SpringCloud系列--Feign 服务调用)已经实现了多个服务之间的Feign调用,服务消费者调用服务提供者,本文记录Feign调用Ribbon负载均衡的服务提供者 GitHub地址:https://github.com/Netflix/ribbon 官方文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-net

  • SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

    1.Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的-套客户端―负载均衡的工具. 简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用.Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等.简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器.我们很容易使用Ribbon实现自定义的负载均

  • SpringCloud Netflix Ribbon源码解析(推荐)

    SpringCloud Netflix Ribbon源码解析 首先会介绍Ribbon 相关的配置和实例的初始化过程,然后讲解Ribbon 是如何与OpenFeign 集成的,接着讲解负载均衡器LoadBalancerCli ent , 最后依次讲解ILoadB alancer的实现和负载均衡策略Rule 的实现. 配置和实例初始化 @RibbonClient 注解可以声明Ribbon 客户端,设置Ribbon 客户端的名称和配置类,configuration 属性可以指定@Configurati

  • springboot默认日志框架选择源码解析(推荐)

    背景: 今天新生成一个springboot项目,然而启动日志,还有mybatis的详细日志无法打印出来,自写程序中打印的日志可以输出:网上找了很多资料,都没法解决问题:于是决定跟一下源码,弄清springboot日志相关的逻辑. 环境配置:macbook: intellij idea community edition 2020.03 : gradle 6.8.3 jdk1.8 : gradle引用包如下: dependencies { compile "com.alibaba:fastjson

  • JetCache 缓存框架的使用及源码解析(推荐)

    目录 一.简介 为什么使用缓存? 使用场景 使用规范 二.如何使用 引入maven依赖 添加配置 配置说明 注解说明 @EnableCreateCacheAnnotation @EnableMethodCache @CacheInvalidate @CacheUpdate @CacheRefresh @CachePenetrationProtect @CreateCache 三.源码解析 项目的各个子模块 常用注解与变量 缓存API Cache接口 AbstractCache抽象类 Abstra

  • Java源码解析之GenericDeclaration详解

    学习别人实现某个功能的设计思路,来提高自己的编程水平.话不多说,下面进入正题. GenericDeclaration 可以声明类型变量的实体的公共接口,也就是说,只有实现了该接口才能在对应的实体上声明(定义)类型变量,这些实体目前只有三个:Class(类).Construstor(构造器).Method(方法)(详见:Java源码解析之TypeVariable详解 源码 public interface GenericDeclaration { //获得声明列表上的类型变量数组 public T

  • Java源码解析之object类

    在源码的阅读过程中,可以了解别人实现某个功能的涉及思路,看看他们是怎么想,怎么做的.接下来,我们看看这篇Java源码解析之object的详细内容. Java基类Object java.lang.Object,Java所有类的父类,在你编写一个类的时候,若无指定父类(没有显式extends一个父类)编译器(一般编译器完成该步骤)会默认的添加Object为该类的父类(可以将该类反编译看其字节码,不过貌似Java7自带的反编译javap现在看不到了). 再说的详细点:假如类A,没有显式继承其他类,编译

  • 深度源码解析Java 线程池的实现原理

    java 系统的运行归根到底是程序的运行,程序的运行归根到底是代码的执行,代码的执行归根到底是虚拟机的执行,虚拟机的执行其实就是操作系统的线程在执行,并且会占用一定的系统资源,如CPU.内存.磁盘.网络等等.所以,如何高效的使用这些资源就是程序员在平时写代码时候的一个努力的方向.本文要说的线程池就是一种对 CPU 利用的优化手段. 线程池,百度百科是这么解释的: 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的

  • Spring源码解析之编程式事务

    一.前言 在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用TransactionTemplate可实现更细粒度的事务控制.声明式事务管理: 基于Spring AOP实现.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务. 声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单(尤其是配合spring boot自动配置,可以说是精简至极!),且大部分业务都可

  • Java源码解析之详解ReentrantLock

    ReentrantLock ReentrantLock是一种可重入的互斥锁,它的行为和作用与关键字synchronized有些类似,在并发场景下可以让多个线程按照一定的顺序访问同一资源.相比synchronized,ReentrantLock多了可扩展的能力,比如我们可以创建一个名为MyReentrantLock的类继承ReentrantLock,并重写部分方法使其更加高效. 当一个线程调用ReentrantLock.lock()方法时,如果ReentrantLock没有被其他线程持有,且不存在

  • Java源码解析之Gateway请求转发

    Gateway请求转发 本期我们主要还是讲解一下Gateway,上一期我们讲解了一下Gateway中进行路由转发的关键角色,过滤器和断言是如何被加载的,上期链接://www.jb51.net/article/211824.htm 好了我们废话不多说,开始今天的Gateway请求转发流程讲解,为了在讲解源码的时候,以防止大家可能会迷糊,博主专门画了一下源码流程图,链接地址://www.jb51.net/article/211824.htm 上一期我们已经知道了相关类的加载,今天直接从源码开始,大家

随机推荐