一、简介
为什么一开始就需要了解这一块,原因就是这块涉及到的组件的调用关系相对独立,更容易理解,而这块也是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等:
而这里IRule仅仅是个接口,netflix提供了好多实现策略,详细如下:
三、深入
通过上面的结构,可以了解到如此多的实现,这里只拿出一个来看看其实现,别的只做描述。这里拿比较简单的RoundRobinRule来说明:
其逻辑比较简单,与其他交互的组件就是从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的平均响应时间。权重算法类似如下: |
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