一、简介

为什么一开始就需要了解这一块,原因就是这块涉及到的组件的调用关系相对独立,更容易理解,而这块也是ribbon的核心之一。

二、接口

ribbon的负载均衡最终都委托给了一个类来实现,那就是IRule,IRule负责不同的策略算法,接口定义如下:

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

通过接口定义可见,IRule需要依赖一个ILoadBalancer,这里我们先暂时抛开不看何谓ILoadBalancer。

只看其核心的方法是Server choose(Object key),即根据key返回Server对象,而Server包含了关键信息,例如host,port等:

A10负载均衡支持SNI ilb负载均衡_A10负载均衡支持SNI


而这里IRule仅仅是个接口,netflix提供了好多实现策略,详细如下:

A10负载均衡支持SNI ilb负载均衡_响应时间_02

三、深入

通过上面的结构,可以了解到如此多的实现,这里只拿出一个来看看其实现,别的只做描述。这里拿比较简单的RoundRobinRule来说明:

A10负载均衡支持SNI ilb负载均衡_A10负载均衡支持SNI_03


其逻辑比较简单,与其他交互的组件就是从ILoadBalancer获取server列表,之后获取下一个下标,返回server,循环10次。

另外,它并没有使用到传入的参数key。

四、总结

下面将不同的策略实现做简单的总结:

序号

类型

策略名

描述

实现简单介绍

1

不依赖于server运行状况

RoundRobinRule

字如其名,轮询获取server

内置计数器,计数器递增与server列表长度取模,作为下标来从server列表获取下一个server

2

RandomRule

字如其名,随机获取server

内置jdk的Random,随机一个小于server列表长度的数,作为下标从server列表来获取下一个server

3

RetryRule

在默认500ms内,通过重试获取到可用server

内部采用RoundRobinRule获取server,如果server不可用,则循环重试获取。监控线程会定时中断重试任务。

4

ClientConfigEnabledRoundRobinRule

轮询选择server

内部依赖RoundRobinRule实现轮询

5

依赖于server运行状况

WeightedResponseTimeRule

根据server响应时间来分配权重,响应时间越小,权重越高,选中的几率越大

每30s执行一次权重计算任务。权重计算以响应时间为依据,响应时间来自于LoadBalancerStats,其中存储了每个server的平均响应时间。权重算法类似如下:

A10负载均衡支持SNI ilb负载均衡_响应时间_04

6

BestAvailableRule

获取并发请求数最小的非故障server

内部依赖LoadBalancerStats来判断server是否故障(断路器打开),同样,从LoadBalancerStats获取当前请求数最小的server

7

AvailabilityFilteringRule

随机获取可用的并且并发数小的server

内部委托了AvailabilityPredicate来实现,依赖LoadBalancerStats来判断server是否故障(断路器打开),同样,从LoadBalancerStats获取当前请求数从而过滤掉并发量大的server

8

ZoneAvoidanceRule

排除不可用区域和性能差的区域,并选择可用的并发数小的server。

与AvailabilityFilteringRule类似其内部同样依赖了AvailabilityPredicate来实现server的判断。

对于zone的判断,依赖ZoneAvoidancePredicate来实现。

默认情况下,ribbon使用的策略是ZoneAvoidanceRule,如果服务没有分区部署(默认情况下,我们的zone都是defaultZone),那么其实ZoneAvoidanceRule就会退化为AvailabilityFilteringRule。

关于如何配置不同的策略,请参见:结合ribbon