负载测试简介
介绍
随着网站和 Web 应用程序的功能越来越丰富和复杂,性能成为开发人员和用户都关心的主要问题。 研究 表明,更快的网站会带来更多的参与度、更多的销售额和更多的流量,因此请务必注意您可以多快地将网站交付给用户并在他们的浏览器中呈现。
这个知识领域的总称是web 性能优化,在过去的几年里,已经开发了许多最佳实践、技术和技术来改善 web 体验。 其中许多技术专注于减少网页的下载大小、优化 JavaScript 以及限制页面所需的单个 HTTP 请求的数量。
在本文中,我们将讨论 Web 性能的另一面:您的服务器响应用户请求的速度有多快? 我们将回顾负载测试的总体情况,逐步制定计划以找到您的服务器的最大实际响应率,并讨论一些开源负载测试软件。
词汇表
在开始之前,让我们澄清一些相关的术语和概念:
延迟衡量服务器响应客户端请求的速度。 通常以毫秒 (ms) 为单位测量,延迟通常称为 响应时间 。 较低的数字表示更快的响应。 延迟是在客户端测量的,从发送请求到收到响应。 此数字中包含网络开销。
吞吐量是服务器在特定时间间隔内可以处理多少请求,通常报告为每秒请求数。
Percentiles 是一种按其在整个样本集中的百分比对结果进行分组的方法。 如果您的第 50 个百分位响应时间是 100 毫秒,这意味着 50% of 请求在 100 毫秒或更短的时间内返回。 下图显示了为什么按百分位查看测量值很有用:
上图显示了一段时间内 Web 服务器的延迟。 尽管平均(平均)响应时间相当一致,但在第 99 个百分位线上有一个很大的峰值。 这意味着 1% of 我们用户的请求执行 甚至比第 99 个百分位测量结果更差 ,而平均值保持相对稳定。 因此,值得查看百分位数以更准确地了解用户的真实体验。
负载测试基础
负载测试是将模拟的 HTTP 流量发送到服务器以测量性能并回答一些重要问题的做法,例如:
- 服务器是否有足够的资源(CPU、内存等)来处理预期的负载?
- 服务器的响应速度是否足够快以提供良好的用户体验?
- 我们的应用程序是否高效运行?
- 我们是否需要扩展我们的服务器硬件,或扩展至多台服务器?
- 是否存在特别占用资源的页面或 API 调用?
负载测试是通过在一台机器(或一组机器)上运行负载测试软件来向另一台机器(或其他更复杂的 Web 服务基础设施)上的 Web 服务器生成大量请求来执行的。 有很多这样的工具可用,我们稍后会看一些特定的软件。 现在,无论您选择什么软件,我们都将讨论相关的负载测试。
负载测试软件的一个常见用途是找到服务器可以处理的每秒最大请求数。 这是通过向服务器发送尽可能多的请求并查看它可以成功返回多少来完成的。
作为了解服务器最大容量的第一步,这很有用,但它并没有为我们提供有关延迟和用户将体验到的实际日常性能的太多信息。 负载很重的服务器每秒可能会返回一千个响应,但如果每个响应需要十秒钟,您的用户可能会不高兴。
下图显示了吞吐量(每秒响应数)和延迟之间的关系:
这只是一个示例,每个设置都会有一个独特的响应配置文件,但总体趋势是更高的负载(每秒更多的请求)会导致更高的延迟。 为了更真实地了解我们的服务器在给定负载下的延迟,我们需要以不同的请求速率进行多次测试。 不是所有的负载测试软件都能做到这一点,但稍后我们将讨论 wrk2
,一个可以执行此功能的命令行负载测试工具。
什么是合理的延迟目标?
尽管 2-5 秒范围内的网站加载时间很常见,但归因于 Web 服务器延迟的那部分时间通常约为 50-200 毫秒。 什么适合您和您的站点取决于太多因素(您的受众、市场、站点的目的、站点是面向用户还是 API 服务等),无法给出更具体的目标数字,但请记住大多数研究表明,每一点速度都很重要,即使是“难以察觉的”改进,综合来看也会带来更好的结果。
现在我们对负载测试有了一个大致的了解,让我们讨论一个具体的计划来探索我们的服务器的性能。
负载测试计划
您可以采取一些常规步骤来了解您的服务器和 Web 应用程序是如何执行和响应负载的。 首先,我们将确保在负载测试期间监控正确的系统资源。 然后,我们将找出我们的服务器每秒能够处理的绝对最大请求数。 最后,我们将找到服务器延迟导致用户无法接受的最大吞吐量。
第 1 步 - 监控资源
我们的负载测试软件将为我们提供有关请求和延迟的信息,但监控其他一些系统指标以查看服务器在处理高流量时是否变得资源受限很有用。
我们最关心的是 CPU 负载和空闲内存:在高负载下观察这些将帮助您在开发应用程序时就如何扩展基础架构和集中精力做出更明智的决定。
如果您已经设置了监控系统(例如 Prometheus 或 Graphite 和 CollectD),那么一切就绪。 如果没有,请通过 SSH 登录到您的 Web 服务器并使用以下命令行工具进行实时监控。
要检查可用内存,您可以使用 free
命令。 将其与 watch
结合以定期(默认每两秒)更新输出:
watch free -h
-h
标志告诉 free
以人类可读的格式而不是字节输出数字:
Output total used free shared buffers cached Mem: 489M 261M 228M 352K 7.5M 213M -/+ buffers/cache: 39M 450M Swap: 0B 0B 0B
上面输出中突出显示的数字表示减去缓冲区和缓存使用后的可用内存。 free
的较新版本更改了输出:
Output total used free shared buff/cache available Mem: 488M 182M 34M 14M 271M 260M Swap: 0B 0B 0B
新的 available
列的计算方式略有不同,但通常表示相同的指标:当前可供应用程序使用的内存。
对于从命令行监视 CPU 使用情况,mpstat 是一个很好的实用程序,它提供了空闲 CPU 资源量的更新视图。 mpstat 默认情况下未在 Ubuntu 上安装。 您可以使用以下命令安装它:
sudo apt-get install sysstat
当您启动 mpstat
时,您需要告诉它您希望更新之间的秒数:
mpstat 2
这将输出一个标题行,然后每两秒输出一行统计信息:
OutputLinux 4.4.0-66-generic (example-server) 08/21/2017 _x86_64_ (4 CPU) 08:06:26 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 08:06:28 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 08:06:30 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
%idle
显示未使用的 CPU 资源百分比。 我们查看 idle 多少而不是 used 多少的原因是因为 CPU 利用率通常分为不同的类别,例如 user CPU 和 [ X186X]系统 CPU。 我们不是在运行中添加这些,而是查看等式的空闲侧。
现在我们可以观察服务器的资源,让我们运行一个初始负载测试来找到我们服务器的最大响应率。
第 2 步 — 找到最大响应率
如前所述,大多数负载测试软件特别适合查找 Web 服务器的最大响应率。 通常,您需要设置的唯一选项是所需的 并发 和测试持续时间。
并发性是对服务器进行多少并行连接的度量。 100 是一个安全的默认选择,但您可以通过检查 Web 服务器的 MaxClients
、MaxThreads
或类似设置来确定它可以处理的同时连接数,从而做出更明智的选择。
除了设置这些选项之外,您还需要选择一个用于测试的 URL。 如果您的软件一次只能处理一个 URL,则值得对几个不同的 URL 进行多次测试,因为处理要求可能在您的主页和需要加载多个数据库查询的产品页面之间有很大差异.
或者,某些负载测试软件允许您指定多个 URL 一次进行测试。 这是更准确地模拟现实世界交通的好方法。 如果您有现有的站点使用数据(来自分析软件或服务器日志),您可以将测试 URL 与观察值紧密匹配。
整理好要测试的一个或多个 URL 后,运行负载测试。 确保您的软件尽可能快地发送请求。 如果您使用的软件要求您选择请求率,请选择一个几乎可以肯定会太大的值。 如果您的软件在请求之间具有可配置的延迟,请将其减少到零。
您应该看到您的 CPU 和内存资源被消耗。 您的 CPU 空闲可能达到 0%,并且您的负载测试客户端可能会收到一些连接错误,因为您的服务器难以跟上所有请求。 这是正常的,因为我们正在将服务器推向极限。
当一切结束后,你的软件会输出一些统计数据,包括每秒请求数。 还要注意 响应时间 :它可能非常糟糕,因为服务器应该已经过度扩展。 因此,每秒请求数并不是服务器实际最大吞吐量的良好指标,但它是进一步探索的良好起点。
接下来,我们将回拨负载并再次测试,以获取有关我们的服务器在没有被推到其绝对限制时如何执行的更多信息。
第 3 步 — 找到最大的实际吞吐量
对于这一步,我们需要使用负载测试软件来稍微降低负载,以测试我们服务器在不同吞吐量水平下的性能。 一些软件通过允许您指定每个请求之间的延迟来做到这一点,但这使得很难以精确的吞吐量为目标。
幸运的是,wrk2
允许您指定精确的每秒请求数目标。 它通过首先运行一些校准请求以使其时间恰到好处来做到这一点。
从上一步中获取最大请求率并将其减半。 以这个新速率运行另一个测试并记下响应时间。 是否还在可接受的范围内?
如果是,则将速率提高到最大值,一边进行测试,直到您的延迟达到您确定可以接受的最大值。 这是您的服务器在用户体验性能下降之前可以处理的 实际 最大响应速率。
注意: 正如术语表中提到的,在测量延迟时,您应该查看第 99 甚至第 99.999 个百分位数,以确保您的 所有 用户经常遇到响应低于您最大可接受阈值的时间。 请记住,大多数网页需要数十个请求来获取所有资产(包括图像、JavaScript、CSS 文件等)并呈现页面。 如果您的网页需要十个请求才能完成,并且您测量的是第 99 个百分位,那么您的页面加载大约 10% of 仍会遇到一个延迟较高的请求。
接下来,我们将查看一些可用于帮助我们实施负载测试计划的开源软件包。
负载测试软件
有许多开源软件包可用于负载测试。 此外,还有许多商业服务将为您运行负载测试基础架构并根据测试数据自动创建图表和报告。 对于需要生成大量负载来测试大规模基础设施的企业来说,这些服务可能是一个不错的选择,因为它们中的大多数运行机器集群来生成比单个服务器更多的请求。
也就是说,一些开源工具也能够在集群模式下运行。 让我们来看看一些比较流行的开源工具,总结一下它们的特点:
抗体
ab(也称为 ApacheBench)是一个简单的单线程命令行工具,用于对 HTTP 服务器进行基准测试。 尽管它最初是作为 Apache HTTP 服务器的一部分分发的,但您可以使用 ab 来测试任何 HTTP 或 HTTPS 服务器。
因为它是单线程的,所以 ab 不能利用多个处理器来发送大量请求。 如果您尝试完全加载功能强大的 Web 服务器,这可能会受到限制。
ab
命令的基本调用如下所示:
ab -n 1000 -c 100 http://example.com/
您指定请求数 (-n
) 和并发性 (-c
),然后给它一个 URL 来获取。 输出(摘录如下)包含每秒请求数、请求时间和不同响应时间百分位数的列表:
Output. . . Requests per second: 734.76 [#/sec] (mean) Time per request: 136.098 [ms] (mean) Time per request: 1.361 [ms] (mean, across all concurrent requests) Transfer rate: 60645.11 [Kbytes/sec] received Percentage of the requests served within a certain time (ms) 50% 133 66% 135 75% 137 80% 139 90% 145 95% 149 98% 150 99% 151 100% 189 (longest request)
JMeter
JMeter 是来自 Apache Software Foundation 的功能强大且功能丰富的负载测试和 功能测试 应用程序。 功能测试意味着 JMeter 还可以进行测试以确保您的网站或应用程序产生正确的输出。
JMeter 有一个用于设置 Test Plans 的 Java GUI:
使用 JMeter 的流量记录网络代理和普通浏览器可以记录测试计划。 这使您可以使用更接近模拟实际使用的流量进行测试。
JMeter 可以以 HTML 报告和其他格式输出百分位信息。
围城
Siege 是另一个命令行负载测试工具,类似于 ab,但有一些不同的功能。 Siege 是多线程的,可以实现相对较高的吞吐量。 它还允许您提供要进行负载测试的多个 URL 的列表。 一个基本的调用如下:
siege -c 100 -t 30s http://example.com/
这需要 100 个并发请求 (-c 100
) 和 30 秒测试 (-t 30s
)。 Siege 输出平均响应时间和请求率:
Output. . . Transactions: 5810 hits Availability: 100.00 % Elapsed time: 29.47 secs Data transferred: 135.13 MB Response time: 0.01 secs Transaction rate: 197.15 trans/sec Throughput: 4.59 MB/sec Concurrency: 2.23 . . .
Siege 没有为其延迟统计数据提供百分位细分。
刺槐
Locust 是一个基于 Python 的负载测试工具,具有用于监控结果的实时 Web UI:
你用 Python 代码编写 Locust 测试场景,允许一些强大的配置,这对那些已经熟悉该语言的人来说很方便。
Locust 也可以在 分布式模式 下运行,您可以在其中运行 Locust 服务器集群并让它们以协调的方式产生负载。 这有助于对强大的 Web 服务基础架构进行负载测试。
Locust 可以在可下载的 CSV 文件中提供详细的统计数据和百分位数信息。
wrk2
wrk2 是一个多线程命令行负载测试工具,能够以指定的请求率产生负载。 它可以提供详细的延迟统计信息,并且可以使用 Lua 编程语言编写脚本。
wrk2 使用 wrk
命令调用(它是原始 wrk
的一个分支):
wrk -t4 -c100 -d30s -R100 --latency http://example.com/
上面的选项指定了四个线程(-t4
,你应该使用你机器上的处理器核心数),100个并发请求(-c100
),三十秒的测试周期([X184X ]),请求速率为每秒 100 个请求 (-R100
)。 最后,我们使用 --latency
请求详细的延迟输出:
Output. . . Latency Distribution (HdrHistogram - Recorded Latency) 50.000% 5.79ms 75.000% 7.58ms 90.000% 10.19ms 99.000% 29.30ms 99.900% 30.69ms 99.990% 31.36ms 99.999% 31.36ms 100.000% 31.36ms . . .
上面的输出是一个摘录——还打印了更详细的延迟百分位数。
结论
在本文中,我们回顾了一些负载测试术语和基本概念,通过了一个计划来找到我们每秒的最大实际请求,观察系统资源以指导未来有关硬件和开发工作的决策,并查看了一些可用的开源负载测试软件。
在测量了基础架构的性能之后,您可能希望根据这些信息采取行动,以尝试改进响应时间并减少服务器负载。 您可能希望通过多台服务器和负载平衡器来扩展或扩展您的 Web 服务器硬件。 您可能会尝试微调您的 Web 服务器配置,以优化它允许的连接数量或它使用的工作进程或线程的数量。 您还可以考虑在内存中缓存经常访问的数据,以减少数据库负载和查询时间。
您可以在 我们的服务器优化标签教程集 中找到上述主题和更多内容。