Ribbon 负载均衡策略

Ribbon 是什么

Ribbon 是 Netflix 公司发布的一个客户端 IPC 库,主要提供以下功能:

  1. 负载均衡(Load Balance)
  2. 容错(Fault tolerance)
  3. 多协议支持(HTTP\TCP\UDP)
  4. 缓存和批处理

负载均衡方案

主流的负载均衡策略可以分为两种:

一种是集中式Load Balance(缩写:LB), 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;

另一种是进程内Load Balance,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

Ribbon 的均衡负载策略

Ribbon 支持多种均衡负载策略,在源代码中,Ribbon 中的 IRule 接口代表均衡负载策略:
image (1).png

实现类 作用
RoundRobinRule 轮询策略
RandomRule 随机策略
RetryRule 先使用轮询策略,如果获取服务失败,则进行重试
WeightedResponseTimeRule RoundRobinRule 的扩展,响应速度越快的服务,权重越高。优先选择权重高的服务
BestAvailableRule 过滤多次发生故障的服务,选择并发量最小的服务
AvailabilityFilteringRule 过滤故障服务,选择并发量小的服务
ZoneAvoidanceRule 默认规则,选择区域内可用性能最高的服务

Ribbon 策略使用

RestTemplate

RestTemplate 是Spring 提供的用于访问Rest 服务的库。在配置类中,通过加 @LoadBalanced 注解,可创建具有负载均衡能力的 RestTemplate 实例:

1
2
3
4
5
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}

更改默认策略

使用 RestTemplate 发起 Rest 请求,会默认采取轮询策略,以下代码可以更换默认策略。

1
2
3
4
@Bean
public IRule ribbonRule() {
return new BestAvailableRule();
}

指定策略

Ribbon 提供更加细粒度的配置策略能力,例如 消费者A 访问 服务者集群节点B 采用轮询策略,而访问 服务者集群节点C 采用随即策略。

  1. 创建客户端访问 服务B的 配置类
    1
    2
    3
    4
    @Configuration
    @RibbonClient(name="SERVICE-B",configuration = RibbonRandomRuleConfiguration.class)
    public class ServiceBRibbonConfiguration {
    }
  2. 创建 Ribbon 策略配置类。注意此类,不能放在 @ComponentSan 扫描的当前包,以及子包下面。对于 SpringBoot 项目来说,就是不能放在启动类所在包,以及子包里面。

    例如:项目启动类在 cn.liaocp.module.blog 中,那这个配置里可以放在 cn.liaocp.module.config 中。

1
2
3
4
5
6
7
8
9
@Configuration
public class RibbonRandomRuleConfiguration {

//Ribbon提供的负载均衡策略
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}

如果上面的类,放在 @ComponentSan 可扫描的包或子包中,项目的全局默认策略变成此配置的策略。

轮询策略算法解析

如果一个服务者有两个集群节点,B 和 C,一个消费者节点 A。

轮询策略的效果:
当消费者 A,第一次请求服务,此时返回的为 B 节点服务者里面的接口。
当消费者 A,第二次请求服务,此时返回的为 C 节点服务者里面的接口。
当消费者 A,第三次请求服务,此时返回的为 B 节点服务者里面的接口。

算法原理

接口的第 N 此请求 % 集群节点数量 = 集群节点的下标数。
通过下标数,在节点列表获取到具体的节点。需要注意,每次重启 N 从 1 开始。

###源码分析
image.png

参考文章:

  1. https://github.com/Netflix/ribbon
  2. https://blog.csdn.net/whiteBearClimb/article/details/108703356
  3. https://www.jianshu.com/p/79b9cf0d0519