老生常谈的负载均衡,你真的懂了吗?
温馨提示:文末有福利哦
负载均衡(Load Balancing)
调度后方的多台机器,以统一的接口对外提供服务,承担此职责的技术组件被称为“负载均衡”。
无论在网关内部建立了多少级的负载均衡,从形式上来说都可以分为两种:四层负载均衡和七层负载均衡。在详细介绍它们是什么以及如何工作之前,我们先来建立两个总体的、概念性的印象。
四层负载均衡的优势是性能高,七层负载均衡的优势是功能强。
做多级混合负载均衡,通常应是低层的负载均衡在前,高层的负载均衡在后(想一想为什么?)。
我们所说的“四层”、“七层”,指的是经典的OSI 七层模型中第四层传输层和第七层应用层,表 4-1 是来自于维基百科上对 OSI 七层模型的介绍(笔者做了简单的中文翻译),这部分属于网络基础知识,这里就不多解释了。后面我们会多次使用到这张表,如你对网络知识并不是特别了解的,可通过维基百科获得进一步的资料。
数据链路层负载均衡
参考上面 OSI 模型的表格,数据链路层传输的内容是数据帧(Frame),譬如常见的以太网帧、ADSL 宽带的 PPP 帧等。我们讨论的具体上下文里,目标必定就是以太网帧了,按照IEEE 802.3标准,最典型的 1500 Bytes MTU 的以太网帧结构如表 4-2 所示。
上述只有请求经过负载均衡器,而服务的响应无须从负载均衡器原路返回的工作模式,整个请求、转发、响应的链路形成一个“三角关系”,所以这种负载均衡模式也常被很形象地称为“三角传输模式”(Direct Server Return,DSR),也有叫“单臂模式”(Single Legged Mode)或者“直接路由”(Direct Routing)。
网络层负载均衡
根据 OSI 七层模型,在第三层网络层传输的单位是分组数据包(Packets),这是一种在分组交换网络(Packet Switching Network,PSN)中传输的结构化数据单位。以 IP 协议为例,一个 IP 数据包由 Headers 和 Payload 两部分组成, Headers 长度最大为 60 Bytes,其中包括了 20 Bytes 的固定数据和最长不超过 40 Bytes 的可选的额外设置组成。按照 IPv4 标准,一个典型的分组数据包的 Headers 部分具有如表 4-3 所示的结构。
尽管因为要封装新的数据包,IP 隧道的转发模式比起直接路由模式效率会有所下降,但由于并没有修改原有数据包中的任何信息,所以 IP 隧道的转发模式仍然具备三角传输的特性,即负载均衡器转发来的请求,可以由真实服务器去直接应答,无须在经过均衡器原路返回。而且由于 IP 隧道工作在网络层,所以可以跨越 VLAN,因此摆脱了直接路由模式中网络侧的约束。此模式从请求到响应的过程如图 4-9 所示。
在流量压力比较大的时候,NAT 模式的负载均衡会带来较大的性能损失,比起直接路由和 IP 隧道模式,甚至会出现数量级上的下降。这点是显而易见的,由负载均衡器代表整个服务集群来进行应答,各个服务器的响应数据都会互相挣抢均衡器的出口带宽,这就好比在家里用 NAT 上网的话,如果有人在下载,你打游戏可能就会觉得卡顿是一个道理,此时整个系统的瓶颈很容易就出现在负载均衡器上。
应用层负载均衡
前面介绍的四层负载均衡工作模式都属于“转发”,即直接将承载着 TCP 报文的底层数据格式(IP 数据包或以太网帧)转发到真实服务器上,此时客户端到响应请求的真实服务器维持着同一条 TCP 通道。但工作在四层之后的负载均衡模式就无法再进行转发了,只能进行代理,此时真实服务器、负载均衡器、客户端三者之间由两条独立的 TCP 通道来维持通信,转发与代理的区别如图 4-11 所示。
“代理”这个词,根据“哪一方能感知到”的原则,可以分为“正向代理”、“反向代理”和“透明代理”三类。正向代理就是我们通常简称的代理,指在客户端设置的、代表客户端与服务器通信的代理服务,它是客户端可知,而对服务器透明的。反向代理是指在设置在服务器这一侧,代表真实服务器来与客户端通信的代理服务,此时它对客户端来说是透明的。至于透明代理是指对双方都透明的,配置在网络中间设备上的代理服务,譬如,架设在路由器上的透明翻墙代理。
根据以上定义,很显然,七层负载均衡器它就属于反向代理中的一种,如果只论网络性能,七层均衡器肯定是无论如何比不过四层均衡器的,它比四层均衡器至少多一轮 TCP 握手,有着跟 NAT 转发模式一样的带宽问题,而且通常要耗费更多的 CPU,因为可用的解析规则远比四层丰富。所以如果用七层均衡器去做下载站、视频站这种流量应用是不合适的,起码不能作为第一级均衡器。但是,如果网站的性能瓶颈并不在于网络性能,要论整个服务集群对外所体现出来的服务性能,七层均衡器就有它的用武之地了。这里面七层均衡器的底气就是来源于它工作在应用层,可以感知应用层通信的具体内容,往往能够做出更明智的决策,玩出更多的花样来。
举个生活中的例子,四层均衡器就像银行的自助排号机,转发效率高且不知疲倦,每一个达到银行的客户根据排号机的顺序,选择对应的窗口接受服务;而七层均衡器就像银行大堂经理,他会先确认客户需要办理的业务,再安排排号。这样办理理财、存取款等业务的客户,会根据银行内部资源得到统一协调处理,加快客户业务办理流程,有一些无须柜台办理的业务,由大堂经理直接就可以解决了,譬如,反向代理的就能够实现静态资源缓存,对于静态资源的请求就可以在反向代理上直接返回,无须转发到真实服务器。
代理的工作模式相信大家应该是比较熟悉的,这里不再展开,只是简单列举了一些七层代理可以实现的功能,以便读者对它“功能强大”有个直观的感受。
所有 CDN 可以做的缓存方面的工作(就是除去 CDN 根据物理位置就近返回这种优化链路的工作外),七层均衡器全都可以实现,譬如静态资源缓存、协议升级、安全防护、访问控制,等等。
七层均衡器可以实现更智能化的路由。譬如,根据 Session 路由,以实现亲和性的集群;根据 URL 路由,实现专职化服务(此时就相当于网关的职责);甚至根据用户身份路由,实现对部分用户的特殊服务(如某些站点的贵宾服务器),等等。
很多微服务架构的系统中,链路治理措施都需要在七层中进行,譬如服务降级、熔断、异常注入,等等。譬如,一台服务器只有出现物理层面或者系统层面的故障,导致无法应答 TCP 请求才能被四层均衡器所感知,进而剔除出服务集群,如果一台服务器能够应答,只是一直在报 500 错,那四层均衡器对此是完全无能为力的,只能由七层均衡器来解决。
均衡策略与实现
负载均衡的两大职责是“选择谁来处理用户请求”和“将用户请求转发过去”。到此我们仅介绍了后者,即请求的转发或代理过程。前者是指均衡器所采取的均衡策略,由于这一块涉及的均衡算法太多,笔者无法逐一展开,所以本节仅从功能和应用的角度去介绍一些常见的均衡策略。
轮循均衡(Round Robin):每一次来自网络的请求轮流分配给内部中的服务器,从 1 至 N 然后重新开始。此种均衡算法适合于集群中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。
权重轮循均衡(Weighted Round Robin):根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。譬如:服务器 A 的权值被设计成 1,B 的权值是 3,C 的权值是 6,则服务器 A、B、C 将分别接收到 10%、30%、60%的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。
随机均衡(Random):把来自客户端的请求随机分配给内部中的多个服务器,在数据足够大的场景下能达到相对均衡的分布。
权重随机均衡(Weighted Random):此种均衡算法类似于权重轮循算法,不过在分配处理请求时是个随机选择的过程。
响应速度均衡(Response Time):负载均衡设备对内部各服务器发出一个探测请求(例如 Ping),然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。此种均衡算法能较好的反映服务器的当前运行状态,但这最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间,而不是客户端与服务器间的最快响应时间。
最少连接数均衡(Least Connection):客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不平衡,并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录,记录当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。此种均衡策略适合长时处理的请求服务,如 FTP 传输。
…………
从实现角度来看,负载均衡器的实现分为“软件均衡器”和“硬件均衡器”两类。在软件均衡器方面,又分为直接建设在操作系统内核的均衡器和应用程序形式的均衡器两种。前者的代表是 LVS(Linux Virtual Server),后者的代表有 Nginx、HAProxy、KeepAlived 等,前者性能会更好,因为无须在内核空间和应用空间中来回复制数据包;而后者的优势是选择广泛,使用方便,功能不受限于内核版本。
在硬件均衡器方面,往往会直接采用应用专用集成电路(Application Specific Integrated Circuit,ASIC)来实现,有专用处理芯片的支持,避免操作系统层面的损耗,得以达到最高的性能。这类的代表就是著名的 F5 和 A10 公司的负载均衡产品。
参考资料:
《凤凰架构:构建可靠的大型分布式系统》,作者是周志明老师,此书豆瓣评分9.2,这本书通俗易懂、深入浅出,对理解分布式系统非常有帮助,推荐大家有空去读一下。
一定要点击👇🏻的 收藏、赞、在看支持一下作者噢~~如果你觉得本文对你有帮助的话!