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