1、认识负载均衡
负载均衡常常指的是服务器端的负载均衡,比如:架设多个服务器来响应用户请求,多个服务器通过一定的管理规则来处理请求的转发。
1.1、服务器端负载均衡
服务器端负载均衡是应对高并发和进行服务器端扩容的重要手段。
服务端负载均衡主要通过在客户端服务器端之间增加负载均衡器来实现。
负载均衡器分类:
- 硬件负载均衡:F5、Radware、Array、A10等硬件设备
- 软件负载均衡:在普通的服务器上安装具有负载均衡功能的软件,以完成请求分发进而实现负载均衡。常见的负载均衡软件有Nginx、LVS、Haproxy等
1.2、客户端负载均衡
客户端负载均衡和服务器端负载均衡的实现原理差不多,它们的区别是:c,而服务器端负载均衡的“服务提供者清单”存储在负载均衡器中。
在客户端负载均衡中,所有客户端节点都管理着一份自己要访问的服务提供者清单,这些清单都是从"服务中心"(Eureka、Consul等)获取的。
2、认识Ribbon
2.1、Ribbon的工作原理
Ribbon是Netflix公司的开源项目,是一款基于HTTP和TCP的客户端负载均衡组件,它是不可以独立部署的。Spring Cloud Ribbon是基于Ribbon实现,基于轮训、随机等规则自动调用服务,也可以根据需要自定义负载均衡算法。
2.2、Ribbon支持的9大负载均衡策略
Ribbon通过IRule接口定义负载均衡策略。IRule接口是负载均衡策略的父接口
源码:
代码语言:javascript复制public interface IRule {
//选择服务器
Server choose(Object var1);
//设置负载均衡器
void setLoadBalancer(ILoadBalancer var1);
//获取负载均衡器
ILoadBalancer getLoadBalancer();
}
定义IRule的主要目的是辅助均衡策略选取合适的服务实例,其默认采用的是线性轮询策略。
2.2.1、线性轮询策略
原理:
- RoundRobbionRule类的choose(ILoadBalancer lb,Object key)方法初始化一个计算器count
- incrementAndGetModulo()方法获取一个下标(是先加1,然后和服务清单总数取模获取到的,不会越界),是一个不断自增长的数
- chooseServer(Object key)方法拿着下标去服务列中取服务,每次循环计算器都加1。如果连续10次了没有取到服务,则会报"No avaliable alive servers after 10 tries form load balancer"警告
2.2.2 、重试策略
重试策略使用在RetryRule类中定义的choose(ILoadBalancer lb,Object key)方法来选择一个服务实例。
原理:
- 如果选到的服务实例正常,则返回数据
- 如果选到的服务实例为null或失效,则choose()方法会在失效时间前不断地进行重试
- 如果超过了失效时间还是没有取到,则返回一个null
2.2.3、加权响应时间策略
原理:
每30s计算一次各个服务实例的响应时间,以响应时间来计算权重。平均时间越短则权重越高,权重越高被选中的概率越高,反之则被选中的概率较低。
2.2.4、随机策略
原理:
- 负载均衡通过upList()和allList()方法获得可用服务实例列表,然后初始化了一个Random对象生成一个不大于服务实例总数的随机数
- choose()方法将该随机数作为下标获取一个服务实例
2.2.5、客户端配置启用线性轮询策略
该策略没有特殊的处理逻辑,一般不直接使用它。
2.2.6、最空闲策略
原理:
该策略是逐个考察各服务实例,然后选择一个最小的并发请求的服务实例来提供服务。
2.2.7、过滤线性轮询策略
原理:
通过内部定义一个过滤器过滤出一部分服务实例清单,然后用线性轮询的方式从过滤出来的服务实例清单中选取一个服务实例。
2.2.8、区域感知轮询策略
原理:
该策略以可用服务器为基础,选择服务实例并对服务实例进行分类。ZoneAoidanceRule类中的有过滤条件,在过滤后,继续采用线性轮询的方式从过滤结果中选择出一个服务实例。
2.2.9、可用性过滤策略
该策略根据服务状态(宕机或繁忙)来分配权重,过滤掉那些因为一直连接失败或高并发服务实例。