Spring Cloud Ribbon
1 前言
Ribbon是Netflix公司开发的一个负载均衡组件,它是Spring Cloud微服务体系弹性扩展的基础组件,与其他组件结合可以发挥出强大的作用。
2 负载均衡概述
业界对于负载均衡有不少分类,最常见的有软负载与硬负载,代表产品是Nginx与F5;还有一种分类方式,那就是服务端负载均衡和作客户端负载均衡。
- 客户端负载均衡
在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端地址列表,这些列表统统都是从服务注册中心获取的;
- 服务端负载均衡
在服务端负载均衡中,客户端节点只知道单一服务代理的地址,服务代理则知道所有服务端的地址。
客户端负载均衡和服务端负载均衡最大的区别在于 服务端地址列表的存储位置,以及负载算法在那里。
3 负载均衡策略
说到Ribbon,就会提到负载均衡,而谈到负载均衡,就会衍生出多种负载均衡策略。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。我们也可以实现自定义负载均衡算法。
默认实现:
ZoneAvoidanceRule(区域权衡策略):复合判断Server所在区域的性能和Server的可用性,轮询选择服务器。
其他规则:
BestAvailableRule(最低并发策略):会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。逐个找服务,如果断路器打开,则忽略。
RoundRobinRule(轮询策略):以简单轮询选择一个服务器。按顺序循环选择一个server。
RandomRule(随机策略):随机选择一个服务器。
AvailabilityFilteringRule(可用过滤策略):会先过滤掉多次访问故障而处于断路器跳闸状态的服务和过滤并发的连接数量超过阀值得服务,然后对剩余的服务列表安装轮询策略进行访问。
WeightedResponseTimeRule(响应时间加权策略):据平均响应时间计算所有的服务的权重,响应时间越快服务权重越大,容易被选中的概率就越高。刚启动时,如果统计信息不中,则使用RoundRobinRule(轮询)策略,等统计的信息足够了会自动的切换到WeightedResponseTimeRule。响应时间长,权重低,被选择的概率低。反之,同样道理。此策略综合了各种因素(网络,磁盘,IO等),这些因素直接影响响应时间。
RetryRule(重试策略):先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败则在指定的时间会进行重试,进行获取可用的服务。如多次获取某个服务失败,就不会再次获取该服务。主要是在一个时间段内,如果选择一个服务不成功,就继续找可用的服务,直到超时。
4 自定义配置
4.1 全局策略设置
使用Ribbon的时候想要全局更改负载均衡策略,需要加一个配置类,如下代码所示:
@Configuration
public class RibbonRuleConfiguration {
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
就这样一个简单的配置,加上之后凡是通过Ribbon的请求都会按照配置的规则来进行。
4.2 基于配置文件的策略设置
client-a:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRul
5 Ribbon脱离Eureka
在默认情况下,Ribbon客户端会从Eureka注册中心读取服务注册信息列表,来达到一种动态负载均衡的功能。如果Eureka是一个供很多人使用的公共注册中心,此时极易产生服务侵入性问题,所以就不要从Eureka中读取服务列表了,而应该在Ribbon客户端自行指定源服务地址,让Ribbon脱离Eureka来使用。
#Ribbon中禁用Eureka
ribbon.eureka.enabled=false
#然后对源服务设定地址列表
ribbon.listOfServers=localhost:8681,localhost:8682
6 码农来洞见
Ribbon作为一个Spring Cloud微服务体系中的负载均衡器,理解其实现原理就显得格外重要。IRule是定义Ribbon负载均衡策略的父接口,所有策略都是基于它实现的。下面做一个引导。
public interface IRule{
public Server choose(Object key);
public void setLoadBalancer(ILoadBalancer lb);
public ILoadBalancer getLoadBalancer();
}
IRule接口一共定义了三个方法,实现类实现choose方法会加入具体的负载均衡策略逻辑。另外两个方法与ILoadBalancer关联起来,在调用过程中,Ribbon是通过ILoadBalancer来关联IRule的,ILoadBalancer的chooseServer方法会转换为调用IRule的choose方法,抽象类AbstractLoadBalancerRule实现了这两个方法,从而将ILoadBalancer与IRule关联起来。再往下走就是具体的实现类了。
Ribbon的可配置性比较强大,若内部配置不能满足需求,可自行根据相关规则增加适用的扩展。
参考资料
官网首页:https://github.com/Netflix/ribbon
ribbon-core: 核心的通用性代码。api一些配置。
ribbon-eureka:基于eureka封装的模块,能快速集成eureka。
ribbon-examples:学习示例。
ribbon-httpclient:基于apache httpClient封装的rest客户端,集成了负载均衡模块,可以直接在项目中使用。
ribbon-loadbalancer:负载均衡模块。
ribbon-transport:基于netty实现多协议的支持。比如http,tcp,udp等。