负载均衡

概述

参考:

Load balancing(负载均衡) 是一种计算机技术,将一组任务分配给一组资源(计算单元)的过程,目的是提高其整体处理效率。

一,什么是负载均衡(Load balancing)

在网站创立初期,我们一般都使用单台机器对台提供集中式服务,但是随着业务量越来越大,无论是性能上还是稳定性上都有了更大的挑战。这时候我们就会想到通过扩容的方式来提供更好的服务。

我们一般会把多台机器组成一个集群对外提供服务。然而,我们的网站对外提供的访问入口都是一个的,比如 www.taobao.com。那么当用户在浏览器输入www.taobao.com的时候如何将用户的请求分发到集群中不同的机器上呢,这就是负载均衡在做的事情。

二,负载均衡按网络七层模型分类

现在我们知道,负载均衡就是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁碟驱动器或其他资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。那么,这种计算机技术的实现方式有多种。大致可以分为以下几种,其中最常用的是四层和七层负载均衡:

  • 二层负载均衡
    • 负载均衡服务器对外依然提供一个 VIP(虚 IP),集群中不同的机器采用相同 IP 地址,但是机器的 MAC 地址不一样。当负载均衡服务器接受到请求之后,通过改写报文的目标 MAC 地址的方式将请求转发到目标机器实现负载均衡。
  • 三层负载均衡
    • 和二层负载均衡类似,负载均衡服务器对外依然提供一个 VIP(虚 IP),但是集群中不同的机器采用不同的 IP 地址。当负载均衡服务器接受到请求之后,根据不同的负载均衡算法,通过 IP 将请求转发至不同的真实服务器。
  • 四层负载均衡:TCP 层的 Load Balance,转发请求
    • 四层负载均衡工作在 OSI 模型的传输层,由于在传输层,只有 TCP/UDP 协议,这两种协议中除了包含源 IP、目标 IP 以外,还包含源端口号及目的端口号。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。
    • 应用场景:对于用户请求一个网站的图片,会根据用户请求中 URL 的地址:端口,转发到后端的服务器上,再由后端服务器处理该请求,这时候要求运维人员记住用户请求图片所在的服务器是哪台
  • 七层负载均衡:HTTP 协议层的反向代理,代理请求
    • 七层负载均衡工作在 OSI 模型的应用层,应用层协议较多,常用 http、radius、dns 等。七层负载就可以基于这些协议来负载。这些应用层协议中会包含很多有意义的内容。比如同一个 Web 服务器的负载均衡,除了根据 IP 加端口进行负载外,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。
    • 应用场景:对于用户请求一个网站的图片,会根据用户请求的 URL 来代理用户的该请求,重新构建请求报文,根据自身的缓存规则,比如一致性哈希算法,找到该图片的位置,然后把请求发送给该设备。

对于一般的应用来说,有了 Nginx 就够了。Nginx 可以用于七层负载均衡。但是对于一些大的网站,一般会采用 DNS+四层负载+七层负载的方式进行多层次负载均衡。

三、四层、七层负载均衡对比

所谓四层即运输层,就是基于 IP + 端口的负载均衡;七层即应用层,就是基于 URL 等应用层信息的负载均衡;

同理,还有基于 MAC 地址的二层负载均衡和基于 IP 地址的三层负载均衡。

换句换说,

二层负载均衡会通过一个虚拟 MAC 地址接收请求,然后再分配到真实的 MAC 地址;

三层负载均衡会通过一个虚拟 IP 地址接收请求,然后再分配到真实的 IP 地址;

四层通过虚拟 IP + 端口接收请求,然后再分配到真实的服务器;

七层通过虚拟的 URL 或主机名接收请求,然后再分配到真实的服务器。

所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量。

比如四层的负载均衡,就是通过发布三层的 IP 地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,

对需要处理的流量进行 NAT 处理,转发至后台服务器,并记录下这个 TCP 或者 UDP 的流量是由哪台服务器处理的,

后续这个连接的所有流量都同样转发到同一台服务器处理。

七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征, 比如同一个 Web 服务器的负载均衡,除了根据 VIP 加 80 端口辨别是否需要处理的流量, 还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。

举个例子,如果你的 Web 服务器分成两组,一组是中文语言的,一组是英文语言的,

那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。

负载均衡器通常称为四层交换机或七层交换机。

四层交换机主要分析 IP 层及 TCP/UDP 层,实现四层流量负载均衡。

七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如 HTTP 协议 URI 或 Cookie 信息。

负载均衡分为 L4 Switch(四层交换),即在 OSI 第 4 层工作,就是 TCP 层啦。

此种 Load Balancer 不理解应用协议(如 HTTP/FTP/MySQL 等等)。例子:LVS,F5。

另一种叫做 L7 Switch(七层交换),OSI 的最高层,应用层。

此时,该 Load Balancer 能理解应用协议。例子: HAProxy,MySQL Proxy。

注意:上面的很多 Load Balancer 既可以做四层交换,也可以做七层交换。

当前可以看到对于 F5, Array 等硬件负载均衡设备本身也是支持 7 层负载均衡的,

同时在 4 层负载均衡的时候我们还可以设置是否进行会话保持等高级特性。

要明白 4 层负载均衡本质是转发,而 7 层负载本质是内容交换和代理,具体说明如下:

四、四层,七层技术原理上的区别

所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

以常见的 TCP 为例,负载均衡设备在接收到第一个来自客户端的 SYN 请求时,即通过上述方式选择一个最佳的服务器, 并对报文中的目标 IP 地址进行修改(改为后端服务器 IP),直接转发给该服务器。 TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。

在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,

再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

以常见的  TCP  为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,

只能先代理最终的服务器和客户端建立连接(TCP 三次握手)后,才可能接收到客户端发送的真正应用层内容的报文, 然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立 TCP 连接。

所以从这个技术原理上来看,七层负载均衡明显地对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。

五、 应用场景的需求

七层应用负载均衡的好处,是使得整个网络更“智能化”, 例如访问一个网站的用户流量,可以通过七层的方式,

将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。

当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。 很多在后台(例如 Nginx 或者 Apache )上部署的功能可以前移到负载均衡设备上,例如客户请求中的 Header 重写,服务器响应中的关键字过滤或者内容插入等功能。

另外一个常常被提到功能就是安全性。网络中最常见的 SYN Flood 攻击,即黑客控制众多源客户端,使用虚假 IP 地址对同一目标发送 SYN 攻击,

通常这种攻击会大量发送 SYN 报文,耗尽服务器上的相关资源,以达到 Denial of Service(DoS) 的目的。

从技术原理上也可以看出,四层模式下这些 SYN 攻击都会被转发到后端的服务器上;

而七层模式下这些 SYN 攻击自然在负载均衡设备上就截止,不会影响后台服务器的正常运营。

另外负载均衡设备可以在七层层面设定多种策略,过滤特定报文,例如 SQL Injection 等应用层面的特定攻击手段,从应用层面进一步提高系统整体安全。

现在的 7 层负载均衡,主要还是着重于应用广泛的 HTTP 协议,所以其应用范围主要是众多的网站或者内部信息平台等基于 B/S 开发的系统。

4 层负载均衡则对应其他 TCP 应用,例如基于 C/S 开发的 ERP 等系统。

负载均衡算法

上面介绍负载均衡技术的时候提到过,负载均衡服务器在决定将请求转发到具体哪台真实服务器的时候,是通过负载均衡算法来实现的。负载均衡算法可以分为两类:静态负载均衡算法和动态负载均衡算法。

静态负载均衡算法包括:轮询,比率,优先权

动态负载均衡算法包括: 最少连接数,最快响应速度,观察方法,预测法,动态性能分配,动态服务器补充,服务质量,服务类型。

轮询(Round Robin):顺序循环将请求一次顺序循环地连接每个服务器。当其中某个服务器发生第二到第 7 层的故障,BIG-IP 就把其从顺序循环队列中拿出,不参加下一次的轮询,直到其恢复正常。

比率(Ratio):给每个服务器分配一个加权值为比例,根椐这个比例,把用户的请求分配到每个服务器。当其中某个服务器发生第二到第 7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配, 直到其恢复正常。

优先权(Priority):给所有服务器分组,给每个组定义优先权,BIG-IP 用户的请求,分配给优先级最高的服务器组(在同一组内,采用轮询或比率算法,分配用户的请求);当最高优先级中所有服务器出现故障,BIG-IP 才将请求送给次优先级的服务器组。这种方式,实际为用户提供一种热备份的方式。

最少的连接方式(Least Connection):传递新的连接给那些进行最少连接处理的服务器。当其中某个服务器发生第二到第 7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配, 直到其恢复正常。

最快模式(Fastest):传递连接给那些响应最快的服务器。当其中某个服务器发生第二到第 7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

观察模式(Observed):连接数目和响应时间以这两项的最佳平衡为依据为新的请求选择服务器。当其中某个服务器发生第二到第 7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

预测模式(Predictive):BIG-IP 利用收集到的服务器当前的性能指标,进行预测分析,选择一台服务器在下一个时间片内,其性能将达到最佳的服务器相应用户的请求。(被 BIG-IP 进行检测)

动态性能分配(Dynamic Ratio-APM):BIG-IP 收集到的应用程序和应用服务器的各项性能参数,动态调整流量分配。

动态服务器补充(Dynamic Server Act.):当主服务器群中因故障导致数量减少时,动态地将备份服务器补充至主服务器群。

服务质量(QoS):按不同的优先级对数据流进行分配。

服务类型(ToS): 按不同的服务类型(在 Type of Field 中标识)负载均衡对数据流进行分配。

Persistence

https://www.nginx.com/resources/glossary/session-persistence/

有时候,后端服务器会缓存用户的请求,在一定时间内,需要让用户的访问使用由该服务器来响应。实现这种需求的技术称为 Session persistence(会话保持)Session stickiness(会话粘性)

实现 Seesion persistence 技术的算法通常都是 Hashing 相关算法。

负载均衡的实现

Nginx/LVS/HAProxy 是目前使用最广泛的三种负载均衡软件。

LVS # 也就是 Linux 虚拟服务器, 是一个由章文嵩博士发起的自由软件项目。使用 LVS 技术要达到的目标是:通过 LVS 提供的负载均衡技术和 Linux 操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。

  • LVS 主要用来做四层负载均衡。

Nginx # 是一个网页服务器,它能反向代理 HTTP, HTTPS, SMTP, POP3, IMAP 的协议链接,以及一个负载均衡器和一个 HTTP 缓存。

  • Nginx 主要用来做七层负载均衡。

HAProxy # 是一个使用 C 语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于 TCP 和 HTTP 的应用程序代理。

  • Haproxy 主要用来做四层负载均衡。