缓慢引发用户流失 — 据 Pingdom 的数据显示,页面加载时长为 5 秒的网站的流失率接近 40%。这意味着什么?如果您的网站加载时间过长,近一半的访问者会弃而访问其他网站。用户一直期望更快的应用速度和更出色的数字体验,因此提高性能对实现业务增长而言至关重要。您一定不希望有着市场需要的产品或服务,却无法为客户提供快速、无缝的体验。
本文分析对比了两款软件应用交付控制器(ADC)的性能,即 Avi Vantage 平台和 NGINX 应用平台。我们测量了客户端请求的延迟时间,这是影响客户端交互的重要指标。
测试方法和收集的指标
我们使用性能测试工具 wrk2
模拟客户端,在规定的时间段内通过 HTTPS 对文件发起连续请求。被测 ADC 数据平面(Avi Service Engine (SE) 或 NGINX Plus)充当反向代理,将请求转发到后端 Web 服务器,并将 Web 服务器生成的响应(文件)返回给客户端。在各种测试运行中,我们通过改变客户端的每秒请求数(RPS)和请求文件的大小来模拟实际流量模式。
在测试期间,我们收集了以下两项性能指标:
- 平均延迟 – 延迟是指客户端从生成请求到接收响应所用的时间。平均值的计算方法是将测试期间所有请求的响应时间相加,然后除以请求数。
- 延迟 95 线 – 将测试期间收集的延迟测量值从高到低(即从延迟时间最长到最短)进行排序。去掉最高的 5% 的测量值,剩下的最高值就是 95% 请求的最大响应延迟时间,即:延迟 95 线。
测试方法
客户端
我们在 Amazon Elastic Compute Cloud(EC2)实例上运行了以下脚本:
wrk2 -t1 -c50 -d180s -Rx --latency https://server.example.com:443/
(有关客户端等所有所用 EC2 实例的规格,请参阅附录。)为了模拟多个客户端同时访问一个基于 Web 的应用,在每次测试中,脚本都会生成一个 wrk2
线程,并与 ADC 数据平面建立 50 个并发连接,然后在 3 分钟内持续请求一个静态文件(文件大小因测试用例而异)。这些参数对应于以下 wrk2
选项:
-t
选项 – 要创建的线程数(1)。-c
选项 – 要创建的 TCP 连接数(50)。-d
选项 – 测试持续的秒数(180 秒或 3 分钟)。-Rx
选项 – 客户端每秒请求数(也称为“客户端 RPS”)。在测试运行中,x 被替换为适当的客户端 RPS 速率。--latency
选项 – 输出结果中包含详细的延迟百分位信息。
如下所述,我们根据 EC2 实例的规格改变请求文件的大小:使用较小规格的实例时为 1 KB,使用较大规格的实例时为 10 KB 和 100 KB。对于 1 KB 和 10 KB 文件,我们将 RPS 速率提高到 1,000;而对于 100 KB 文件,则将 RPS 速率提高到 100。针对不同的 RPS 速率和文件大小组合,我们总共执行了 20 次测试。下图显示了 20 次测试结果的平均值。
所有请求均通过 HTTPS 发出。我们使用了支持 256 位密钥长度和完美前向保密( Perfect Forward Secrecy)的 ECC;SSL 加密套件为 ECDHE-ECDSA-AES256-GCM-SHA384
。
Avi 反向代理:配置和版本
我们从 AWS Marketplace 获取并部署了 Avi Vantage 17.2.7 版本。Avi 允许您为 SE 选择 AWS 实例类型,但不允许选择底层操作系统。Avi Controller 会预先选择部署 SE 的操作系统;在测试时,我们选用的是 Ubuntu 14.04.5 LTS。
NGINX 反向代理:配置和版本
与 Avi Vantage 平台将控制平面(其 Controller 组件)和数据平面(SE)捆绑在一起不同,NGINX 控制平面(NGINX Controller)与数据平面(NGINX Plus)完全分离。您可将 NGINX Plus 实例更新到任何版本,或者更改为任何支持的操作系统,而无需更新 NGINX Controller。这样一来,您就能够灵活选择 NGINX Plus 版本和操作系统版本,从而轻松进行更新。得益于这种灵活性,我们在 Ubuntu 16.04 上部署了一个 NGINX Plus R17 实例。
在 NGINX Controller GUI 中,我们为 NGINX Plus 反向代理配置了一个可支持 100 个上游连接的缓存。该配置支持在反向代理和上游服务器之间启用 keepalive 连接,有助于提高性能。
NGINX Plus Web 服务器:配置和版本
如前面的拓扑图所示,我们在所有测试中均将 NGINX Plus R17 用作 Web 服务器。
性能测试结果
t2.medium 实例的延迟
在第一次测试中,我们在 t2.medium 实例上分别部署了 Avi SE 和 NGINX Plus。所请求的文件大小为 1 KB。下图中 X 轴显示客户端 RPS 速率,Y 轴显示延迟(以秒为单位)。每种 RPS 速率下的延迟时间越短越好。
两个延迟测量结果的模式基本相同,只是 Y 轴上的时间尺度不同。就平均延迟和延迟 95 线的测量值来看,在延迟增加到可察觉的水平之前,NGINX Plus 的 RPS 速率几乎是 Avi SE 的 2.5 倍(6,000 vs. 2,500)。为何 Avi SE 在 RPS 速率如此低的情况下会延迟骤增?要回答这个问题,让我们来进一步研究一下在 Avi SE 上连续运行的 20 次测试,看看客户端 RPS 为 2,500 时的平均延迟和延迟 95 线。
如下表所示,在 Avi SE 上以 2,500 RPS 速率连续运行第 17 次测试时,平均延迟骤增至 14 秒以上,同时延迟 95 线也攀升至 35 秒以上。
测试运行 | 平均延迟(毫秒) | 延迟 95 线(毫秒) |
---|---|---|
1 | 1.926 | 3.245 |
2 | 6.603 | 10.287 |
3 | 2.278 | 3.371 |
4 | 1.943 | 3.227 |
5 | 2.015 | 3.353 |
6 | 6.633 | 10.167 |
7 | 1.932 | 3.277 |
8 | 1.983 | 3.301 |
9 | 1.955 | 3.333 |
10 | 7.223 | 10.399 |
11 | 2.048 | 3.353 |
12 | 2.021 | 3.375 |
13 | 1.930 | 3.175 |
14 | 1.960 | 3.175 |
15 | 6.980 | 10.495 |
16 | 1.934 | 3.289 |
17 | 14020 | 35350 |
18 | 27800 | 50500 |
19 | 28280 | 47500 |
20 | 26400 | 47800 |
要了解延迟激增的原因,首先要知道 t2 实例是“突发性能”实例。这意味着它一直只能消耗基准量的可用 vCPU(我们的 t2.medium 实例为 40%)。在运行期间,该实例还会积累 CPU 积分,每个积分相当于 1 个 vCPU 以 100% 使用率运行 1 分钟。要使用超过其基准 vCPU 分配(突发)的计算能力,实例必须支付积分,当积分用完时,实例会被降回其基准 CPU 分配。
htop
(在第 17 次测试运行期间出现延迟飙升后,以详细模式运行)的输出结果以图形方式显示了节流情况:
标记为 1 和 2 的线条对应 t2.medium 实例的 2 个 CPU,描述了每个 CPU 用于不同用途的比例:绿色为用户进程,红色为内核进程等。青色部分格外显眼,因为它占了总体 CPU 使用率的大部分,表示 CPU 窃取时间。在广义虚拟化上下文中,该时间是指“当 hypervisor 为另一个虚拟处理器提供服务时,虚拟 CPU 等待物理 CPU 的时间百分比”。对于 EC2 突发性能实例,它代表该实例因 CPU 积分耗尽而不允许使用的 CPU 容量。
在低于 2,500 的 RPS 速率下,Avi SE 能够完成所有 20 次测试运行,而不会超出其基线分配和 CPU 积分。然而,当 RPS 速率达到 2,500 时,它在第 17 次测试运行中耗尽了积分。延迟激增近 10 倍,因为 Avi 无法高效使用基准 CPU 分配来同步处理快速传入的请求。与 Avi SE 相比,NGINX Plus 使用 CPU 的效率要高得多,因此直到 6,000 RPS 速率下才会耗尽其 CPU 分配和积分。
c4.large 实例的延迟
突发性能实例最适合小型突发工作负载,当 CPU 积分耗尽时,其性能会迅速下降。在实际部署中,通常最好选择以稳定方式消耗 CPU 的实例类型,因为它不会受到 CPU 积分耗尽的影响。Amazon 称其计算优化实例适用于高性能 Web 服务器,因此我们使用在 c4.large 实例上运行的 Avi SE 和 NGINX Plus 重复进行了测试。
测试设置和方法与 t2.medium 实例相同,只是客户端请求的文件更大,分别为 10 KB 和 100 KB,而非 1 KB。
10 KB 文件的延迟
下图显示了客户端请求 10 KB 文件时的平均延迟和延迟 95 线。同样,每种 RPS 速率下的延迟越低越好。
与在 t2.medium 实例上测试得到的两个延迟测量结果的模式基本相同,只是 Y 轴上的时间尺度不同。NGINX Plus 的性能再次超过 Avi SE,高出 70% 以上;直到处理约 7,200 RPS 时,它才出现延迟增加,而 Avi SE 仅处理 4,200 RPS 时延迟便会飙升。
如下表所示,我们的测试还显示,即使在达到 Avi SE 延迟峰值时的 RPS 速率(4,200)之前,Avi SE 在每种 RPS 速率下的延迟都高于 NGINX Plus。在两款产品延迟最接近的 RPS 速率(2000 RPS)下,Avi SE 的平均延迟仍是 NGINX Plus 的 23 倍(54 毫秒 vs. 2.3 毫秒),其延迟 95 线是 NGINX Plus 的 79 倍(317 毫秒 vs. 4.0 毫秒)。
在 4,000 RPS 速率(略低于 Avi SE 延迟峰值时的速率)下,平均延迟倍数增长到 69 倍(160 毫秒 vs. 2.3 毫秒),延迟 95 线倍数增长到 128 倍(526 毫秒 vs. 4.1 毫秒)。在高于 Avi SE 延迟峰值时的 RPS 速率下,该倍数呈爆炸式增长,在 6,000 RPS 速率下差距最大:平均延迟为 7666 倍(23 秒 vs. 3.0 毫秒),延迟 95 线为 8346 倍(43.4 秒 vs. 5.2 毫秒)。
当 NGINX Plus 在 7,200 RPS 速率下出现了延迟峰值后,Avi SE 的性能与其最为接近。即便如此,Avi SE 的最低延迟从未低于 NGINX Plus 的 2 倍(在 10,000 RPS 速率下,Avi SE 的延迟 95 线为 93.5 秒,而 NGINX Plus 则为 45.0 秒)。
客户端 RPS | 平均延迟 | 延迟 95 线 | ||
---|---|---|---|---|
Avi SE | NGINX Plus | Avi SE | NGINX Plus | |
1000 | 84 毫秒 | 1.7 毫秒 | 540 毫秒 | 2.6 毫秒 |
2000 | 54 毫秒 | 2.3 毫秒 | 317 毫秒 | 4.0 毫秒 |
3000 | 134 毫秒 | 2.2 毫秒 | 447 毫秒 | 4.2 毫秒 |
4000 | 160 毫秒 | 2.3 毫秒 | 526 毫秒 | 4.1 毫秒 |
5000 | 8.8 秒 | 2.7 毫秒 | 19.6 秒 | 5.1 毫秒 |
6000 | 23.0 秒 | 3.0 毫秒 | 43.4 秒 | 5.2 毫秒 |
7000 | 33.0 秒 | 4.3 毫秒 | 61.0 秒 | 14.7 毫秒 |
8000 | 40.0 秒 | 6.86 秒 | 74.2 秒 | 13.8 秒 |
9000 | 46.8 秒 | 16.6 秒 | 85.0 秒 | 31.1 秒 |
10000 | 51.6 秒 | 24.4 秒 | 93.5 秒 | 45.0 秒 |
100 KB 文件的延迟
在下一组测试运行中,我们将请求文件的大小增加到 100 KB。
对于这种文件大小,两款产品的 RPS 都急剧下降,但 NGINX Plus 仍然优于 Avi SE,高出近 40% — NGINX Plus 要到处理约 720 RPS 时才会出现明显的延迟增加,而 Avi SE 仅处理 520 RPS 时延迟便会飙升。
在使用 10 KB 文件进行的测试中,Avi SE 在每种 RPS 速率下的延迟也均高于 NGINX Plus。下表显示,两款产品之间的延迟倍数不像在处理 10 KB 文件时那么大,但仍然差距显著。Avi SE 延迟峰值前的最低倍数为 17 倍,即 400 RPS 速率下的平均延迟(185 毫秒 vs. 10.7毫秒)。
客户端 RPS | 平均延迟 | 第 95 百分位的延迟 | ||
---|---|---|---|---|
Avi SE | NGINX Plus | Avi SE | NGINX Plus | |
100 | 100 毫秒 | 5.0 毫秒 | 325 毫秒 | 6.5 毫秒 |
200 | 275 毫秒 | 9.5 毫秒 | 955 毫秒 | 12.5 毫秒 |
300 | 190 毫秒 | 7.9 毫秒 | 700 毫秒 | 10.3 毫秒 |
400 | 185 毫秒 | 10.7 毫秒 | 665 毫秒 | 14.0 毫秒 |
500 | 500 毫秒 | 8.0 毫秒 | 1.9 秒 | 10.4 毫秒 |
600 | 1.8 秒 | 9.3 毫秒 | 6.3 秒 | 12.4 毫秒 |
700 | 15.6 秒 | 2.2 毫秒 | 32.3 秒 | 3.0 毫秒 |
800 | 25.5 秒 | 2.4 秒 | 48.4 秒 | 8.1 秒 |
900 | 33.1 秒 | 12.9 秒 | 61.2 秒 | 26.5 |
1000 | 39.2 秒 | 20.8 秒 | 71.9 秒 | 40.0 秒 |
c4.large 实例的 CPU 使用率
我们最后的测试重点关注在 c4.large 实例上运行的 Avi SE 和 NGINX Plus 的总体 CPU 使用率。我们使用 10 KB 和 100 KB 文件进行了测试。
请求 10 KB 文件时,Avi SE 在大约 5,000 RPS 下达到 100% 的 CPU 使用率,而 NGINX Plus 则在大约 8,000 RPS 下达到 100% 的 CPU 使用率,这表明 NGINX Plus 的性能高出 60%。这两款产品的 CPU 使用率达到 100% 与延迟峰值之间存在明显相关性,Avi SE 和 NGINX Plus 分别在 4,200 RPS 和 7,200 RPS 下出现了延迟峰值。
使用 100 KB 文件测试所得的结果更出乎所料。Avi SE 处理的最高速率为 520 RPS,因为此时其 CPU 使用率达到 100%。NGINX Plus 的性能高出近 40%,最高速率为 720 RPS*。但请注意,NGINX Plus 此时只使用了不到 25% 的可用 CPU;速率上限为 720 RPS,不是因为 NGINX Plus 的处理能力限制,而是因为测试环境中的网络带宽限制。与 Avi SE 将 EC2 实例 CPU 跑满相比,NGINX Plus 提供了可靠的性能,同时仍有充足的 CPU 周期可用于 EC2 实例上运行的其他任务。
* 该图显示最大值为 600 和 800 RPS,但这是绘图软件的限制所致 — 我们以 100 RPS 为增量进行测试,最大值出现在以这些速率进行的测试运行中。
总结
我们在一个实际测试用例中对 NGINX 和 Avi Vantage 进行了大量测试,其中客户端在大约 12 小时内持续生成流量,请求率稳步上升。
测试结果总结如下:
-
NGINX 能够更高效地利用 CPU,因此延迟更低。
- 在突发性能实例(在我们的测试中为 t2.medium)上运行时,Avi 消耗 CPU 积分余额的速度快于 NGINX。
- 在没有 CPU 积分限制(在我们的测试中为 c4.large)的稳定实例上运行,并且在较高的恒定客户端负载下,NGINX 能够在出现延迟峰值之前处理更多 RPS — 请求 10 KB 文件时,RPS 处理速率高出约 70%,请求 100 KB 文件时,RPS 处理速率高出约 40%。
- 在请求 100 KB 文件时,100% CPU 使用率与 Avi 可处理的峰值 RPS 直接相关。相比之下,NGINX Plus 从未达到 100% CPU,而只是受限于可用网络带宽。
- 在 c4.large 实例上进行的每次延迟测试中,NGINX 的性能都优于 Avi,即使当 RPS 速率低于 Avi 延迟峰值下的速率时也是如此。
如前所述,Avi Vantage 不允许您为 Avi SE 实例选择操作系统。因此,如果在操作系统中发现安全漏洞,您将无法升级到操作系统厂商提供的修补版本,必须等待 Avi 发布修复了安全问题的新版 Avi Controller。这可能会使您的所有应用长时间暴露于危险之中。
附录:Amazon EC2 规格
以下表格总结了测试环境中使用的 Amazon EC2 实例的规格。
在每项测试中,实例均位于同一 AWS 区域。
在 t2.medium 实例上进行测试
角色 | 实例类型 | vCPUs | RAM (GB) |
---|---|---|---|
客户端 | t2.micro | 1 | 1 |
反向代理(Avi SE 或 NGINX Plus) | t2.medium | 2 | 4 |
NGINX Plus Web 服务器 | t2.micro | 1 | 1 |
在 c4.large 实例上进行测试
角色 | 实例类型 | vCPUs | RAM (GB) |
---|---|---|---|
客户端 | c4.large | 2 | 3.75 |
反向代理(Avi SE 或 NGINX Plus) | c4.large | 2 | 3.75 |
NGINX Plus Web 服务器 | c4.large | 2 | 3.75 |