高并发中如何做到负载均衡

负载均衡

Posted by TBKK on December 10, 2019

什么是负载均衡

用白话来讲,就是领导分配任务的时候发现A太忙了,手上全是活儿,然后就让B来做。这就是负载均衡。

负载均衡的方式

DNS负载均衡

DNS负载均衡实时上是最初级的负载均衡,也是最常用的负载均衡。 即将统一个地址解析到不同的IP地址。

DNS域名解析负载均衡有如下优点:

  1. 将负载均衡的工作交给DNS,省去了网站管理维护负载均衡服务器的麻烦。
  2. 技术实现比较灵活、方便,简单易行,成本低,使用于大多数TCP/IP应用。
  3. 对于部署在服务器上的应用来说不需要进行任何的代码修改即可实现不同机器上的应用访问。
  4. 服务器可以位于互联网的任意位置。
  5. 同时许多DNS还支持基于地理位置的域名解析,即会将域名解析成距离用户地理最近的一个服务器地址,这样就可以加速用户访问,改善性能。

DNS域名解析也存在如下缺点:

  1. 有缓存,不能及时刷新
  2. 没有负载均衡策略
  3. 可能会造成额外的网络问题。

软负载均衡

顾名思义,即用软件方式来做负载均衡,最典型的方式就是使用Nginx,Haproxy,LVS

Nginx

所有的流量打向Nginx,再由Nginx进行分发,从而形成负载均衡能力。 image

Nginx的单点故障问题如何解决呢? 可以采用Nginx + keeplived 来解决。 image

那如果一台Nginx的能力已经不足以支撑了怎么办呢? 可以在Nginx的外围再加一层负载 image

上图中,为什么选择LVS? 其实上图的LVS的部分可以选很多,比如Haproxy,LVS,F5

  • Haproxy :其实并没有彻底解决问题,还是会和nginx存在同一的问题,即凡是经过此节点进入的流量都必须冲此节点出去。
  • LVS:彻底解决了此问题,他可以将流量转移到单个nginx上,形成无瓶颈的负载均衡
  • F5:土豪使用的硬件负载均衡,唯一的问题就是贵。

硬负载均衡

F5是负载均衡产品的一个品牌,其地位类似于原来诺基亚在手机品牌中的位置。除了F5以外,Radware、Array、A10、Cisco、深信服和华夏创新都是负载均衡的牌子,因为F5在这类产品中影响最大,所以经常说F5负载均衡。

负载均衡策略

  • 轮询

轮询。作为非常经典的负载均衡策略,早期该策略应用地非常广泛。其原理很简单,给每个请求标记一个序号,然后将请求依次派发到服务器节点中,适用于集群中各个节点提供服务能力等同且无状态的场景。其缺点也非常明显,该策略将节点视为等同,与实际中复杂的环境不符。加权轮询为轮询的一个改进策略,每个节点会有权重属性,但是因为权重的设置难以做到随实际情况变化,仍有一定的不足。

  • 随机

随机。与轮询相似,只是不需要对每个请求进行编号,每次随机取一个。同样地,该策略也将后端的每个节点是为等同的。另外同样也有改进的加权随机的算法,不再赘述。

  • 最小响应时间

通过记录每次请求所需的时间,得出平均的响应时间,然后根据响应时间选择最小的响应时间。该策略能较好地反应服务器的状态,但是由于是平均响应时间的关系,时间上有些滞后,无法满足快速响应的要求。因此在此基础之上,会有一些改进版本的策略,如只计算最近若干次的平均时间的策略等。

  • 最小并发数

客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生较大的不同,并没有达到真正的负载均衡。最小并发数的策略则是记录了当前时刻,每个备选节点正在处理的事务数,然后选择并发数最小的节点。该策略能够快速地反应服务器的当前状况,较为合理地将负责分配均匀,适用于对当前系统负载较为敏感的场景。

其他负载均衡

在微服务环境下的注册中心的使用,也是负载均衡的一种使用场景,比如Spring Cloud Ribbon

RPC调用中也有使用到服务的负载均衡算法:

public enum LoadBalance {

    RANDOM(new YoyoRpcLoadBalanceRandomStrategy()),
    ROUND(new YoyoRpcLoadBalanceRoundStrategy()),
    LRU(new YoyoRpcLoadBalanceLRUStrategy()),
    LFU(new YoyoRpcLoadBalanceLFUStrategy()),
    CONSISTENT_HASH(new YoyoRpcLoadBalanceConsistentHashStrategy());
    
}

上面是YoyoRpc的负载均衡策略。 具体代码可以在(https://github.com/tbkk/yoyo-rpc)看到