本节将详细介绍负载均衡器的工作原理,相信读者在阅读后能够对这一概念有更深入的理解。
在实际环境中,QPS(每秒查询率)通常低于保持 TCP 连接的客户端数量。也就是说,打开应用的用户并非每秒都会发起一次 API 请求,平均每隔几秒才会有一次操作。假设这个时间为 4 秒一次,那么:如果有 20 万个客户端在线,每个客户端设备平均每 4 秒发送一个 HTTPS 请求,QPS 为200000 ÷ 4 = 50000
。
Nginx 不仅需要建立 TCP 连接,还需要将 TCP 连接中发送过来的数据包与某个进程/线程进行匹配,同时还需要对 HTTP 协议的信息进行解析、识别、转换、添加。因此,Nginx 也有其 QPS 上限:
在 2015 年主流的服务器 CPU 上,Nginx 官方在进行了极限优化的情况下进行了反向代理性能测试。在完整执行“建立 TCP 连接-发送 HTTPS 请求-断开 TCP 连接”这样一整个“网络事务”的情况下,最高性能为 60000 QPS(SSL TPS RSA 2048bit)。
假设我们使用最新的服务器硬件,当虚拟机 CPU 达到 32 vCore 的时候,未经优化的单机 Nginx 性能就已经达到极限,能承受大约 1 万 HTTPS QPS,对应的连接用户就是 4 万,这就是 Nginx 在单台 x86 物理服务器上的极限。
我们假设单台 Kong 应用网关的极限为 1 万 QPS,于是我们就需要五台 Kong。那么这五台 Kong 前面的 TCP 负载均衡器为何能够扛住呢?因为 TCP 负载均衡器要做的事情比 Kong 少非常多:它只需要在 IP 层做少量的工作即可。
TCP 协议是一种“可靠地传输信息”的方法,它不仅有三次握手四次挥手等复杂的控制流程,还会对每一个报文段进行排序、确认、重发等操作来保证最终数据的完整和正确。因此,TCP 本身就是一种需要很多资源处理的单点
。现在我们开始拆分这个单点。
我们假设一个含有负载均衡器的系统:客户端 IP 为 123.123.123.123
,负载均衡器的 IP 为 110.242.68.3
(公网)和 10.0.0.100
(私网),五台 Kong 服务器的 IP 为 10.0.0.1
~ 10.0.0.5
,那么这个系统的架构就如图 5-8 所示。
负载均衡器的工作过程如下:
负载均衡器接收客户端数据包(报文)的过程如下:
在接收到客户端的 IP 报文后,负载均衡器会寻找一台上游服务器,准备将数据发送过去:
负载均衡器会在内存中创建两个五元组:
左侧五元组
右侧五元组
然后,负载均衡器会关联这两个五元组:对两侧发来的数据包(报文)进行拆包和修改(两个地址+两个端口),并从另一侧发送出去。
对于阅读过笔者《软件工程师需要了解的网络知识》系列文章的读者来说,应该能够一眼看出,这就是网关的工作模式,你家几百块的路由器主要执行的就是这个任务。
通过前面的内容我们可以发现,负载均衡器/网关只需要执行两个主要任务:建立五元组并关联,以及修改数据包的地址和端口并将其发送出去。这个过程在网络领域被称为 NAT(网络地址转换)。
由于这个操作相对简单,大部分工作可以通过专用硬件来完成。例如,可以开发专门用于存储和关联五元组的芯片,以及专门的 NPU(网络数据包处理器)来进行快速的数据修改。正因为可以使用低性能的专用硬件来实现,家用路由器才能以低于 300 元的终端售价实现超过 1Gbit/S 的 NAT 性能。
与负载均衡器只需执行两个任务相比,Kong 网关需要真正地与客户端建立 TCP 连接。具体来说,它需要进行以下操作:
这一系列操作流程较长,且经常需要进行配置修改。如果设计专用硬件来实现,可能会过于复杂,并且收益可能低于投入。因此,使用通用 CPU 加软件的解决方案更加合适。
在商业负载均衡公司中,应用网关也被称为七层负载均衡,因为它工作在 OSI 七层网络模型的第七层。而我们讨论的负载均衡工作在 IP 层的称为四层负载均衡,工作在 OSI 七层网络模型的第四层。读者以后看到 L4、L7 这两个词时,应该能一眼看穿它们了,其实一点都不神秘。
在一个 TCP 负载均衡器下挂载五个安装了 Kong 应用网关的 6 vCore 虚拟机,再下挂 125 台 8 vCore 的 PHP 虚拟机——静山平台的五万 QPS 终于被系统给支撑住了。此时静山平台的架构如图 5-9 所示。
📙 高并发的哲学原理 《Philosophical Principles of High Concurrency》
Copyright © 2023 吕文翰