您当前的位置: 首页 >  spring

一一哥Sun

暂无认证

  • 3浏览

    0关注

    622博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Day17_12_SpringCloud教程之Ribbon详解

一一哥Sun 发布时间:2019-07-15 08:45:07 ,浏览量:3

Ribbon详解 一. 负载均衡分类

1. 服务端负载均衡: 一般常用就是Nginx+Tomcat集群,由Nginx负责接收请求,按照设置的算法(轮询,加权轮询,随机,加权随机,源地址哈希,最小连接数)将请求转发至后端.

也要有一个心跳监测模块,及时去掉不可用的服务节点,用来维护一个可用的服务节点清单.

大型公司一般都用F5硬件负载均衡.

2. 客户端负载均衡: 如果将可用服务节点清单挪到Client端,就是客户端负载均衡了.在Spring Cloud中,Ribbon结合Eureka,客户端从注册中心拿到服务节点列表,按照算法取出一个地址,进行调用.

二. Ribbon简介 1. 概述

实际开发中一般不会让网址直接访问代码服务器(小项目除外),通常是通过nginx进行反向代理和负载均衡.而在Springcloud里我们用了另外2个组件来代替nginx的这两个功能,Ribbon就是代替负载均衡的组件.

通常在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的.Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign.

2. Ribbon 客户端负载均衡简介

Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等.Bibbon 的架构图如下所示:

简单的说,SpringCloud Ribbon 是一个基于HTTP和TCP的客户端负载均衡工具.SpringCloud 将面向服务的REST 模板请求自动转换成客户端负载均衡的服务调用.我们可以在配置文件中列出Load Balancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法.

客户端负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一.通常意思上的负载均衡是指服务端负载均衡,其中又分为硬件负载均衡和软件负载均衡.硬件和软件负载基本原理图如下所示:

客户端负载均衡中所有客户端节点都要维护着自己要访问的服务端清单,这些服务端的清单来自于服务注册中心(Eureka).

Ribbon is a client side load balancer
which gives you a lot of control over the behaviour 
of HTTP and TCP clients. Feign already uses Ribbon, 
so if you are using @FeignClient then this section also applies.

在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中某一个服务提供者实例.

3. Ribbon的常见组件
  • 1️⃣. ServerList: 负载均衡使用的服务器列表这个列表会缓存在负载均衡器中,并定期更新.当Ribbon与Eureka结合使用时,ServerList的实现类就是DiscoveryEnabledNIWSServerList,它会保存Eureka Server中注册的服务实例表.

  • 2️⃣. ServerListFilter: 服务器列表过滤器,这是一个接口,主要用于对Service Consumer获取到的服务器列表进行预过滤,过滤的结果也是ServerList. Ribbon提供了多种过滤器的实现.

  • 3️⃣. IPing: 探测服务实例是否存活的策略.

  • 4️⃣. IRule: 负载均衡策略,其实现类表述的策略包括: 轮询、随机、根据响应时间加权等.

  • 5️⃣. ILoadBalancer: 负载均衡器. 这也是一个接口,Ribbon为其提供了多个实现,比如ZoneAwareLoadBalancer.

  • 6️⃣. RestClient: 服务调用器,顾名思义,这就是负载均衡后,Ribbon向Service Provider发起REST请求的工具.

4. Ribbon负载均衡算法

Ribbon的负载均衡默认使用的最经典的Round Robin轮询算法.Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等.当然,我们也可为Ribbon实现自定义的负载均衡算法.

Ribbon的负载均衡是基于IRule接口实现的,IRule有三个方法,其中choose()是根据key来获取server,setLoadBalancer()和getLoadBalancer()是用来设置和获取ILoadBalancer的.源码如下:

public interface IRule{ 
    public Server choose(Object key);
    public void setLoadBalancer(ILoadBalancer lb); 
    public ILoadBalancer getLoadBalancer();
}

IRule有很多默认的实现类,这些实现类根据不同的算法和逻辑来处理负载均衡,默认的实现类如下:

  • 1️⃣. BestAvailableRule 选择最小请求数;

  • 2️⃣. ClientConfigEnabledRoundRobinRule 轮询;

  • 3️⃣. RandomRule 随机选择一个server;

  • 4️⃣. RoundRobinRule 轮询选择server;

  • 5️⃣. RetryRule 根据轮询的方式重试;

  • 6️⃣. WeightedResponseTimeRule 根据响应时间去分配一个weight,weight越低,被选择的可能性就越低;

  • 7️⃣. ZoneAvoidanceRule 根据server的zone区域和可用性来轮询选择.

这些默认的实现类是可以满足需求的,如果有特殊的需求,可以自己实现,IRule的类结构如下:

5. Ribbon工作流程
  • 1️⃣. 第一步先选择 Eureka Server,获取可用服务列表,从可用的服务列表中它优先选择在同一个Zone且负载较少的Server;

  • 2️⃣. 第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址.其中Ribbon提供了多种策略,例如轮询round robin、随机Random、根据响应时间加权等.

三. Ribbon和Feign实现原理 1. Ribbon原理

Ribbon实现的关键点是利用了RestTemplate的拦截器机制,在拦截器中实现Ribbon的负载均衡.负载均衡的基本实现就是利用applicationName从服务注册中心获取可用的服务地址列表,然后通过一定算法负载,决定使用哪一个服务地址来进行http调用.

2. Ribbon内部实现分为2个部分
  • 1️⃣. 负载均衡算法;

  • 2️⃣. app_name转成具体的ip:port

对于第2点,Ribbon从本质上是利用了RestTemplate的Interceptor进行了扩展.

SpringCloud中,consumer在发起真正的请求之前,解析URL中的provider_app_name,这个是通过Eureka的DiscoverClient实现中获取到对应的多个ip和端口组合,然后通过某种负载均衡算法进行选择,再然后通过RestTemplate的Interceptor来处理这个映射.

3. Feign

Feign是对接口做文章,在接口上添加注解,消费者通过调用接口的形式进行服务消费.

在Spring体系中,只要是通过调用接口来进行某个操作的,应该都是使用了动态代理技术,比如MyBatis中通过接口对应到对应的XML中的SQL.

在Spring解析的时候,核心有2个步骤:

  • 1️⃣.通过接口来动态注册Bean;

  • 2️⃣.对接口方法进行动态代理,比如Feign就是解析@GetMapping这类注解将其转为对应的Http Get请求.

四. Ribbon 超时与重试

通过Ribbon进行服务间HTTP调用时,可以进行超时和重试的设置.

client-b: #被调用的service name

ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000
  MaxAutoRetries: 1 #对第一次请求的服务的重试次数
  MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
  OkToRetryOnAllOperations: true

 

关注
打赏
1665624836
查看更多评论
立即登录/注册

微信扫码登录

0.0377s