ribbon的版本是:ribbon-loadbalancer-2.3.0
一.IRule:定义了选择负载均衡策略的基本操作。通过调用choose()方法,就可以选择具体的负载均衡策略。
package com
.netflix
.loadbalancer
;
public interface IRule{
public Server
choose(Object key
);
public void setLoadBalancer(ILoadBalancer lb
);
public ILoadBalancer
getLoadBalancer();
}
二.ILoadBalancer 接口定义了ribbon负载均衡的常用操作
package com
.netflix
.loadbalancer
;
import java
.util
.List
;
public interface ILoadBalancer {
public void addServers(List
<Server> newServers
);
public Server
chooseServer(Object key
);
public void markServerDown(Server server
);
@Deprecated
public List
<Server> getServerList(boolean availableOnly
);
public List
<Server> getReachableServers();
public List
<Server> getAllServers();
三.AbstractLoadBalancerRule实现了IRule接口和IClientConfigAware接口,主要对IRule接口的2个方法进行了简单封装。
AbstractLoadBalancerRule是每个负载均衡策略需要直接继承的类,Ribbon提供的几个负载均衡策略,都继承了这个抽象类。同理,我们如果需要自定义负载均衡策略,也要继承这个抽象类。
package com
.netflix
.loadbalancer
;
import com
.netflix
.client
.IClientConfigAware
;
public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware
{
private ILoadBalancer lb
;
@Override
public void setLoadBalancer(ILoadBalancer lb
){
this.lb
= lb
;
}
@Override
public ILoadBalancer
getLoadBalancer(){
return lb
;
}
}
四.AbstractLoadBalancerRule的实现类就是ribbon的具体负载均衡策略
1,轮询策略(RoundRobinRule)
2,随机策略(RandomRule)
3,可用过滤策略(AvailabilityFilteringRule)
4,响应时间权重策略(WeightedResponseTimeRule)
5,轮询失败重试策略(RetryRule)
6,并发量最小可用策略(BestAvailableRule)
7,复合判断server所在区域的性能和server的可用性选择server (ZoneAvoidanceRule)
策略名策略描述实现说明
RandomRule随机选择一个 server在 index 上随机,选择 index 对应位置的 ServerRoundRobinRule轮询选择 server轮询 index,选择 index 对应位置的 serverZoneAvoidanceRule复合判断 server 所在区域的性能和 server 的可用性选择 server使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 来判断是否选择某个 server。ZoneAvoidancePredicate 判断判定一个 zone 的运行性能是否可用,剔除不可用的 zone(的所有 server);AvailabilityPredicate 用于过滤掉连接数过多的 server。BestAvailableRule选择一个最小并发请求的 server逐个考察 server,如果 server 被 tripped 了则忽略,在选择其中activeRequestsCount 最小的 serverAvailabilityFilteringRule过滤掉那些因为一直连接失败的被标记为 circuit tripped 的后端 server,并过滤掉那些高并发的的后端 server(activeConnections 超过配置的阈值)使用一个 AvailabilityPredicate 来包含过滤 server 的逻辑,其实就就是检查 status 里记录的各个 server 的运行状态WeightedResponseTimeRule根据 server 的响应时间分配一个 weight,响应时间越长,weight 越小,被选中的可能性越低一个后台线程定期的从 status 里面读取评价响应时间,为每个 server 计算一个 weight。weight 的计算也比较简单,responseTime 减去每个 server 自己平均的 responseTime 是 server 的权重。当刚开始运行,没有形成 status 时,使用 RoundRobinRule 策略选择 server。RetryRule对选定的负载均衡策略机上重试机制在一个配置时间段内当选择 server 不成功,则一直尝试使用 subRule 的方式选择一个可用的 server
默认情况下,Ribbon 采用 ZoneAvoidanceRule 规则。因为大多数公司是单机房,所以一般只有一个 zone,而 ZoneAvoidanceRule 在仅有一个 zone 的情况下,会退化成轮询的选择方式,所以会和 RoundRobinRule 规则类似。
经典的负载均衡规则可以整理如下: 轮询(Round Robin) or 加权轮询(Weighted Round Robin) 随机(Random) or 加权随机(Weighted Random) 源地址哈希(Hash) or 一致性哈希(ConsistentHash) 最少连接数(Least Connections) 最小响应时间(ResponseTime)
五.BaseLoadBalancer是一个负载均衡器,是ribbon框架提供的负载均衡器。Spring Cloud对ribbon封装以后,直接调用ribbon的负载均衡器来实现微服务客户端的负载均衡。
ribbon框架本身提供了几个负载均衡器,BaseLoadBalancer只是其中之一。
Spring Cloud提供了2个接口:ServiceInstanceChooser和LoadBalancerClient,这2个接口就是客户端负载均衡的定义。具体实现类是RibbonLoadBalancerClient。RibbonLoadBalancerClient#choose()方法根据微服务实例的serviceId,然后使用配置的负载均衡策略,打到对于的微服务实例节点上。
执行逻辑:
Spring Cloud RibbonLoadBalancerClient#choose()调用ribbon框架的BaseLoadBalancer.BaseLoadBalancer#chooseServer()选择具体的负载均衡策略(RoundRibonRule),然后执行。
六.自定义负载均衡策略
Ribbon不仅实现了几种负载均衡策略,也为开发者提供了自定义负载均衡策略的支持。 自定义负载均衡策略有3个关键点:
继承抽象类AbstractLoadBalancerRule自定义的负载均衡策略类,不能放在@ComponentScan所扫描的当前包和子包下。在主启动类上添加@RibbonClient注解,或者在配置文件中指定哪个微服务使用自定义负载均衡策略
在自定义 Ribbon 配置的时候,会有全局和客户端两种级别。相比来说,客户端级别是更细粒度的配置。针对每个服务,Spring Cloud Netflix Ribbon 会创建一个 Ribbon 客户端,并且使用服务名作为 Ribbon 客户端的名字。
@RibbonClient注解的使用方法如下: @RibbonClient(name=“微服务名称”, configuration=“自定义配置类.class”) #配置文件中配置项如下: 服务名称.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule