Apache Bench – 快速指南
Apache Bench – 快速指南
Apache Bench – 概述
性能测试已被证明对企业的成功至关重要。表现不佳的网站不仅会面临经济损失,有时还会导致法律后果。
没有人愿意在重要的在线交互(例如购买、在线考试、账单支付等)中忍受一个性能缓慢、不可靠的站点。随着 Internet 的普及,替代方案的范围是巨大的。失去客户比获得客户更容易,而绩效是关键的游戏规则改变者。
需要负载测试工具
如果我们能理解什么是负载测试工具的需求,它就会给我们使用它的理由和动力。一些著名的商业网站在访问量大时遭受了严重的停机。电子商务网站大量投资于广告活动,但未投资于负载测试。因此,当营销带来流量时,他们无法确保最佳系统性能。
另一个常见的忽略负载测试的例子是 WordPress 网站中的“错误建立连接”。因此,最好在将网站或应用程序部署到生产环境之前对其进行负载测试。在进行更详细的测试之前,快速为项目建立最佳情况是很好的。
什么是 Apache 工作台?
Apache Bench (ab) 是来自 Apache 组织的一个工具,用于对超文本传输协议 (HTTP) Web 服务器进行基准测试。尽管它旨在衡量 Apache Web 服务器的性能,但它也可用于测试任何其他同样出色的 Web 服务器。使用此工具,您可以快速了解您的 Web 服务器每秒能够处理多少请求。
Apache Bench 的特点
让我们看看 Apache Bench 的重要特性和局限性。下面列出了功能和限制 –
-
作为一个开源软件,它是免费提供的。
-
它是一个简单的命令行计算机程序。
-
它是一个独立于平台的工具。这意味着它可以在 Linux/Unix 或 Windows 服务器上同样好地调用。
-
它可以仅对 Web 服务器进行负载和性能测试 – HTTP 或 HTTPS。
-
它不可扩展。
无论并发级别如何(由 -c 标志指定),Apache Bench 都只使用一个操作系统线程。因此,在对大容量服务器进行基准测试时,Apache Bench 的单个实例本身可能是一个瓶颈。为了使目标 URL 完全饱和,如果您的服务器有多个处理器内核,最好并行使用 Apache Bench 的其他实例。
预防
您需要注意 Apache Bench 中没有指令在运行测试时在特定时间间隔内增加并发性。因此,使用 ab 运行负载测试相当于拒绝服务 (DOS) 攻击。如果您要进行长时间的重载测试,建议您通知并事先征得您的 VPS 服务提供商的许可。他们将为您分配适当的时间间隔或为负载测试任务转移您的节点。
其次,如果你只是为了从你的VPS(成为测试节点)学习Apache Bench,而长时间连续测试第三方网站,那么你的VPS公网IP极有可能被第三方网站屏蔽永久性。在这种情况下,您将无法使用相同的 IP 连接到该网站。但是,如果您以后真的想连接到该网站,唯一的解决方案是与目标网站的系统管理员交谈,或者在您的 VPS 服务提供商的帮助下创建一个具有不同 IP 的服务器的新实例。
警告过您之后,让我向您保证,本教程中的所有测试都足够安全,并且不属于系统管理员通常所说的“系统滥用”做法。
Apache Bench – 环境设置
在本章中,我们将指导您如何在 VPS 上为 Apache Bench 设置环境。
系统要求
-
内存– 128 MB
-
磁盘空间– 无最低要求
-
操作系统– 无最低要求
安装 Apache 工作台
Apache Bench 是一个独立的应用程序,不依赖于 Apache Web 服务器的安装。以下是安装 Apache Bench 的两步过程。
步骤 1 – 更新包数据库。
# apt-get update
请注意,终端命令前的符号 # 表示 root 用户正在发出该命令。
第 2 步– 安装 apache2 utils 包以访问 Apache Bench。
# apt-get install apache2-utils
Apache Bench 现已安装。如果您想测试托管在同一 VPS 上的 Web 应用程序,那么仅安装 Apache Web 服务器就足够了 –
# apt-get install apache2
作为 Apache 实用程序,Apache Bench 会在安装 Apache Web 服务器时自动安装。
验证 Apache Bench 安装
现在让我们看看如何验证 Apache Bench 安装。以下代码将有助于验证安装 –
# ab -V
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/
当您看到上述终端输出时,表示您已成功安装 Apache Bench。
创建特权 Sudo 用户
从安全的角度来看,系统管理员创建一个 sudo 用户而不是作为 root 工作被认为是一个很好的做法。为此,我们将创建一个名为 test 的测试用户 –
# useradd -m -d /home/test -g sudo test
让我们为新用户设置密码 –
# passwd test
系统将提示用户 test 输入新密码。您可以输入一个简单的密码,因为我们只是在测试,而不是部署到生产服务器。通常sudo命令会提示你提供sudo用户密码;建议不要使用复杂的密码,因为过程变得繁琐。
输出
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
测试 Apache.org 网站
在本节中,我们将测试 Apache.org 网站。让我们首先切换到 sudo 用户测试 –
# su test
首先,我们将测试 Apache 组织的网站https://www.apache.org/。我们将首先运行命令,然后理解输出 –
$ ab -n 100 -c 10 https://www.apache.org/
这里-n是为基准测试会话执行的请求数。默认是只执行一个请求,这通常会导致不具代表性的基准测试结果。
和-c是并发和表示多个请求的数量在一个时间执行。默认为一次一个请求。
所以在这个测试中,Apache Bench 将向 Apache 组织服务器发出 100 个并发为 10 的请求。
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.apache.org (be patient).....done Server Software: Apache/2.4.7 Server Hostname: www.apache.org Server Port: 443 SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256 Document Path: / Document Length: 58769 bytes Concurrency Level: 10 Time taken for tests: 1.004 seconds Complete requests: 100 Failed requests: 0 Total transferred: 5911100 bytes HTML transferred: 5876900 bytes Requests per second: 99.56 [#/sec] (mean) Time per request: 100.444 [ms] (mean) Time per request: 10.044 [ms] (mean, across all concurrent requests) Transfer rate: 5747.06 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 39 46 30.9 41 263 Processing: 37 40 21.7 38 255 Waiting: 12 15 21.7 13 230 Total: 77 86 37.5 79 301 Percentage of the requests served within a certain time (ms) 50% 79 66% 79 75% 80 80% 80 90% 82 95% 84 98% 296 99% 301 100% 301 (longest request)
运行我们的第一个测试后,很容易识别此命令的使用模式,如下所示 –
# ab [options .....] URL
在哪里,
-
ab – Apache Bench 命令
-
options – 我们要执行的特定任务的标志
-
URL – 我们要测试的路径 url
了解输出值
我们需要了解不同的metric,才能理解ab返回的各种输出值。列表如下 –
-
服务器软件– 它是第一次成功返回的 HTTP 标头中返回的 Web 服务器的名称。
-
服务器主机名– 它是命令行上给出的 DNS 或 IP 地址。
-
服务器端口– 这是 ab 连接的端口。如果命令行上没有给出端口,则默认为 http 的 80 和 https 的 443。
-
SSL/TLS 协议– 这是客户端和服务器之间协商的协议参数。只有在使用 SSL 时才会打印。
-
文档路径– 这是从命令行字符串解析的请求 URI。
-
文档长度– 第一个成功返回的文档的大小(以字节为单位)。如果测试期间文档长度发生变化,则响应被视为错误。
-
并发级别– 这是测试期间使用的并发客户端(相当于 Web 浏览器)的数量。
-
Time Taken for Tests – 这是从创建第一个套接字连接到收到最后一个响应所花费的时间。
-
Complete Requests – 收到的成功响应的数量。
-
失败的请求– 被视为失败的请求数。如果数字大于零,将打印另一行,显示由于连接、读取、不正确的内容长度或异常而失败的请求数。
-
Total Transferred – 从服务器接收的总字节数。这个数字本质上是通过线路发送的字节数。
-
HTML Transferred – 从服务器接收的文档字节总数。此数字不包括在 HTTP 标头中收到的字节
-
每秒请求数– 这是每秒的请求数。该值是请求数除以总时间所得的结果。
-
Time per request – 每个请求花费的平均时间。第一个值使用公式 concurrency * timetaken * 1000 / done 计算,而第二个值使用公式 timetaken * 1000 / done 计算
-
传输率–传输率由公式 totalread / 1024 / timetaken 计算。
负载测试输出的快速分析
从 ab 命令了解输出值的标题后,让我们尝试分析和理解初始测试的输出值 –
-
Apache 组织正在使用他们自己的 Web 服务器软件 – Apache(版本 2.4.7)
-
由于 https,服务器正在侦听端口 443。如果它是 http,它将是 80(默认)。
-
对于 100 个请求,传输的总数据为 58769 字节。
-
测试在 1.004 秒内完成。没有失败的请求。
-
每秒请求数 – 99.56。这被认为是一个相当不错的数字。
-
每个请求的时间 – 100.444 毫秒(对于 10 个并发请求)。所以在所有请求中,它是 100.444 ms/10 = 10.044 ms。
-
传输速率 – 1338.39 [Kbytes/sec] 接收。
-
在连接时间统计中,您可以观察到许多请求必须等待几秒钟。这可能是由于 apache Web 服务器将请求放入等待队列。
在我们的第一次测试中,我们测试了托管在不同服务器上的应用程序(即 www.apache.org)。在本教程的后面部分,我们将测试托管在运行 ab 测试的同一服务器上的示例 Web 应用程序。这是为了便于学习和演示。理想情况下,为了准确测量,主机节点和测试节点应该不同。
为了更好地学习 ab,您应该在本教程中继续比较并观察不同情况下输出值的变化情况。
绘制 Apache Bench 的输出
在这里,我们将绘制相关结果,以查看服务器随着请求数量的增加而花费的时间。为此,我们将在前一个命令中添加-g选项,后跟将保存 ab 输出数据的文件名(此处为 out.data) –
$ ab -n 100 -c 10 -g out.data https://www.apache.org/
现在让我们在创建绘图之前查看out.data –
$ less out.data
输出
starttime seconds ctime dtime ttime wait Tue May 30 12:11:37 2017 1496160697 40 38 77 13 Tue May 30 12:11:37 2017 1496160697 42 38 79 13 Tue May 30 12:11:37 2017 1496160697 41 38 80 13 ...
现在让我们了解out.data文件中的列标题–
-
starttime – 这是呼叫开始的日期和时间。
-
seconds – 与 starttime 相同,但采用 Unix 时间戳格式(date -d @1496160697 返回 starttime 输出)。
-
ctime – 这是连接时间。
-
dtime – 这是处理时间。
-
ttime – 这是总时间(它是 ctime 和 dtime 的总和,数学上是 ttime = ctime + dtime)。
-
等待– 这是等待时间。
有关这些多个项目如何相互关联的图形可视化,请查看下图 –
如果我们在终端上工作或图形不可用,gnuplot是一个很好的选择。我们将通过以下步骤快速了解它。
让我们安装并启动 gnuplot –
$ sudo apt-get install gnuplot $ gnuplot
输出
G N U P L O T Version 4.6 patchlevel 6 last modified September 2014 Build System: Linux x86_64 Copyright (C) 1986-1993, 1998, 2004, 2007-2014 Thomas Williams, Colin Kelley and many others gnuplot home: http://www.gnuplot.info faq, bugs, etc: type "help FAQ" immediate help: type "help" (plot window: hit 'h') Terminal type set to 'qt' gnuplot>
由于我们在终端上工作并假设图形不可用,我们可以选择哑终端,它将通过终端本身以 ASCII 格式输出。这有助于我们通过这个快速工具了解我们的情节是什么样的。现在让我们为 ASCII 绘图准备终端。
gnuplot> set terminal dumb
输出
Terminal type set to 'dumb' Options are 'feed size 79, 24'
由于我们的 gnuplot 终端现在已准备好进行 ASCII 绘图,让我们绘制out.data文件中的数据–
gnuplot> plot "out.data" using 9 w l
输出
1400 ++-----+------+-----+------+------+------+------+-----+------+-----++ + + + + + + +"out.data" using 9 ****** + | | 1200 ++ ******************************************** | ******************* | 1000 ++ * ++ | * | | * | 800 ++ * ++ | * | | * | 600 ++ * ++ | * | | * | 400 ++ * ++ | * | 200 ++ * ++ | * | +**** + + + + + + + + + + 0 ++-----+------+-----+------+------+------+------+-----+------+-----++ 0 10 20 30 40 50 60 70 80 90 100
我们已经绘制了第 9 列中与请求数量相关的 ttime,总时间(以毫秒为单位)。我们可以注意到,对于最初的 10 个请求,总时间在近 100 毫秒,对于接下来的 30 个请求(从 10th 到 40th),它增加到 1100 毫秒,依此类推。根据您的out.data ,您的情节必须有所不同。
测试我们的示例应用程序
在上一章中,我们了解了 Apache Bench 测试第三方网站的基本使用方法。在本节中,我们将使用此工具在我们自己的服务器上测试 Web 应用程序。为了尽可能保持本教程的独立性,我们选择安装一个 Python 应用程序进行演示;您可以根据自己的专业水平选择任何其他语言,如 PHP 或 Ruby。
安装 Python
通常,Python 默认安装在 Linux 服务器上。
安装 Bottle 框架并创建一个简单的应用程序
Bottle 是一个用 python 编写的用于创建 web 应用程序的微框架,pip 是一个 python 包管理器。在终端中输入以下命令来安装 Bottle –
$ sudo apt-get install python-pip $ sudo pip install bottle
现在让我们创建一个小的 Bottle 应用程序。为此,创建一个目录并在其中移动 –
$ mkdir webapp $ cd webapp
我们将在 webapp 目录中创建一个新的 Python 脚本app.py –
$ vim app.py
现在,在 app.py 文件中编写以下代码 –
from bottle import Bottle, run app = Bottle() @app.route('/') @app.route('/hello') def hello(): return "Hello World!" run(app, host = 'localhost', port = 8080)
添加以上行后,保存并关闭文件。保存文件后,我们可以运行 python 脚本来启动应用程序 –
$ python app.py
输出
Bottle v0.12.7 server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit.
此输出显示我们的应用程序正在主机http://localhost上的本地计算机上运行并侦听端口8080。
让我们检查我们的应用程序是否正确响应 HTTP 请求。由于此终端在不退出 Bottle 应用程序的情况下无法接受任何输入,因此我们需要使用另一个终端登录我们的 VPS。使用另一个终端登录 VPS 后,您可以通过在新终端中键入以下代码来导航到您的应用程序。
$ lynx http://localhost:8080/
Lynx 是一个命令行浏览器,通常默认安装在各种 Linux 发行版中,例如 Debian 和 Ubuntu。如果您看到以下输出,则表示您的应用运行良好。
输出
如果您看到以上输出,则意味着我们的应用程序已上线并准备好进行测试。
使用开发性 Web 服务器测试应用程序
请注意,ab 中存在一个错误,无法在 localhost 上测试应用程序。因此,我们将在 app.py 文件中将主机从 localhost 更改为 127.0.0.1。因此文件将更改为以下内容 –
from bottle import Bottle, run app = Bottle() @app.route('/') @app.route('/hello') def hello(): return "Hello World!" run(app, host = '127.0.0.1', port = 8080)
现在让我们通过在运行 lynx 命令的同一终端上键入以下命令来测试我们的应用程序 –
$ ab -n 100 -c 10 http://127.0.0.1:8080/hello
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: WSGIServer/0.1 Server Hostname: 127.0.0.1 Server Port: 8080 Document Path: /hello Document Length: 12 bytes Concurrency Level: 10 Time taken for tests: 0.203 seconds Complete requests: 100 Failed requests: 0 Total transferred: 16500 bytes HTML transferred: 1200 bytes Requests per second: 493.78 [#/sec] (mean) Time per request: 20.252 [ms] (mean) Time per request: 2.025 [ms] (mean, across all concurrent requests) Transfer rate: 79.56 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 1 6 28.2 2 202 Waiting: 1 6 28.2 2 202 Total: 1 6 28.2 2 202 Percentage of the requests served within a certain time (ms) 50% 2 66% 2 75% 2 80% 2 90% 2 95% 2 98% 202 99% 202 100% 202 (longest request)
虽然第一个终端上的输出将是(100 次)如下 –
... 127.0.0.1 - - [10/Jun/2017 04:30:26] "GET /hello HTTP/1.0" 200 12 127.0.0.1 - - [10/Jun/2017 04:30:26] "GET /hello HTTP/1.0" 200 12 127.0.0.1 - - [10/Jun/2017 04:30:26] "GET /hello HTTP/1.0" 200 12 ...
您可以观察与初始测试相比,ab 结果的各种值是如何变化的。
使用多线程 Web 服务器测试应用程序
在之前的 ab 测试中,我们使用了 Bottle 框架中捆绑的默认 Web 服务器。
现在我们将使用多线程服务器更改单线程默认 Web 服务器。因此,让我们安装一个像cherrypy或gunicorn这样的多线程Web 服务器库,并告诉Bottle 使用它。我们在这里选择了 gunicorn 进行演示(您也可以选择其他一些) –
$ sudo apt-get install gunicorn
并修改文件,即从默认 Web 服务器更改为 gunicorn –
... run(server = 'gunicorn'...) ...
让我们在第二个终端中测试该应用程序。
$ ab -n 100 -c 10 http://127.0.0.1:8080/hello
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: gunicorn/19.0.0 Server Hostname: 127.0.0.1 Server Port: 8080 Document Path: /hello Document Length: 12 bytes Concurrency Level: 10 Time taken for tests: 0.031 seconds Complete requests: 100 Failed requests: 0 Total transferred: 17200 bytes HTML transferred: 1200 bytes Requests per second: 3252.77 [#/sec] (mean) Time per request: 3.074 [ms] (mean) Time per request: 0.307 [ms] (mean, across all concurrent requests) Transfer rate: 546.36 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.9 0 4 Processing: 1 2 0.7 3 4 Waiting: 0 2 0.8 2 3 Total: 2 3 0.6 3 5 WARNING: The median and mean for the initial connection time are not within a normal deviation These results are probably not that reliable. WARNING: The median and mean for the processing time are not within a normal deviation These results are probably not that reliable. Percentage of the requests served within a certain time (ms) 50% 3 66% 3 75% 3 80% 3 90% 4 95% 5 98% 5 99% 5 100% 5 (longest request)
观察每秒请求数如何从 493 增加到 3252。这意味着 gunicorn 适合作为 python 应用程序的生产服务器。
同时测试多个 URL
在本章中,我们将学习如何同时测试多个 URL。为此,我们需要编辑我们的应用程序文件 app.py 以包含两个 URL –
from bottle import Bottle, run app = Bottle() @app.route('/') @app.route('/hello1') def hello(): return "Hello World! It is first URL." @app.route('/hello2') def hello(): return "Hello World! It is second URL." run(app,server = 'gunicorn',host = '127.0.0.1', port = 8080)
创建一个简单的 Shell 脚本
您可以通过创建带有多个 ab 调用的 shell 脚本来完成此操作。创建一个文件 test.sh 并向其中添加以下几行 –
ab -n 100 -c 10 http://127.0.0.1:8080/hello1 ab -n 100 -c 10 http://127.0.0.1:8080/hello2
添加以上行后,保存并关闭文件。使文件可执行 –
chmod u+x test.sh
现在让我们运行脚本 –
./test.sh
为了避免重复和清晰的目的,我们将只显示 ab 输出的相关部分,用点表示省略了哪些部分,如下所示。
输出
. . . Document Path: /hello1 Document Length: 732 bytes Concurrency Level: 10 Time taken for tests: 0.040 seconds Complete requests: 100 Failed requests: 0 Non-2xx responses: 100 Total transferred: 90000 bytes HTML transferred: 73200 bytes Requests per second: 2496.13 [#/sec] (mean) Time per request: 4.006 [ms] (mean) Time per request: 0.401 [ms] (mean, across all concurrent requests) Transfer rate: 2193.87 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.8 0 3 Processing: 1 3 1.0 4 5 Waiting: 0 3 1.2 4 4 Total: 1 4 0.6 4 5 WARNING: The median and mean for the processing time are not within a normal deviation These results are probably not that reliable. . . .
将 Apache Bench 输出保存到文件的 Shell 脚本
您可以通过创建带有多个 ab 调用的 shell 脚本将 Apache Bench 输出保存到文件。在每一行的末尾,放置一个&; 这使命令在后台运行,并让下一个命令开始执行。您还需要使用 <filename> 将输出重定向到每个 url 的文件。例如,我们的文件 test.sh 修改后将如下所示 –
$ ab -n 100 -c 10 http://127.0.0.1:8080/hello1 > test1.txt & $ ab -n 100 -c 10 http://127.0.0.1:8080/hello2 > test2.txt &
这里,test1.txt和test2.txt是保存输出数据的文件。
您可以检查上面的脚本是否创建了两个文件,test1.txt 和 test2.txt,其中包含相应 URL 的 ab 输出 –
$ ls -l
输出
... -rw-r--r-- 1 root root 5225 May 30 12:11 out.data -rwxr--r-- 1 root root 118 Jun 10 12:24 test.sh -rw-r--r-- 1 root root 1291 Jun 10 12:31 test1.txt -rwxr--r-- 1 root root 91 Jun 10 13:22 test2.sh -rw-r--r-- 1 root root 1291 Jun 10 12:31 test2.txt ...
警戒情况
在使用 ab 时,您应该在没有警告的情况下警惕失败的测试。例如,如果您检查错误的 URL,您可能会得到类似以下内容(我们特意更改了此处的端口)。
$ ab -l -r -n 100 -c 10 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:805/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: Server Hostname: 127.0.0.1 Server Port: 805 Document Path: / Document Length: Variable Concurrency Level: 10 Time taken for tests: 0.002 seconds Complete requests: 100 Failed requests: 150 (Connect: 0, Receive: 100, Length: 0, Exceptions: 50) Keep-Alive requests: 0 Total transferred: 0 bytes HTML transferred: 0 bytes Requests per second: 44984.26 [#/sec] (mean) Time per request: 0.222 [ms] (mean) Time per request: 0.022 [ms] (mean, across all concurrent requests) Transfer rate: 0.00 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 0 0.2 0 0 Waiting: 0 0 0.0 0 0 Total: 0 0 0.2 0 0 Percentage of the requests served within a certain time (ms) 50% 0 66% 0 75% 0 80% 0 90% 0 95% 0 98% 0 99% 0 100% 0 (longest request)
准备测试动态页面
在本章中,我们将了解测试动态页面所需的准备工作。服务器端动态网页是由处理服务器端脚本的应用服务器控制其构造的网页。apache bench 只能对服务器端动态网页进行负载测试。
并发级别和请求总数
并发级别应低于请求总数。
$ ab -l -r -n 30 -c 80 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
输出
ab: Cannot use concurrency level greater than total number of requests Usage: ab [options] [http[s]://]hostname[:port]/path
标志的使用
在本节中,我们将描述一些重要标志与 ab 命令的使用。我们将交替使用术语、选项和标志。
详细 -v
如果存在多个失败的请求,可以使用详细选项进行分析和调试。负载测试失败的一个常见迹象是测试完成得非常快,并且它提供了一个很好的每秒请求数值。但这将是一个错误的基准。要确定成功或失败,您可以使用-v 2选项,它将每个响应的正文和标头转储到终端输出。以下命令描述了一个用例 –
$ ab -n 1 -v 2 http://www.generic-example-URL.com/
输出
LOG: header received: HTTP/1.0 200 OK … Content-Length: 2548687
当然,如果您正在测试可变响应或在出现任何错误时返回非 200 HTTP 代码,您应该简单地忽略使用-l选项的长度检查。当我们在后续章节中启动 web2py 应用程序时,我们很快就会看到非 200 HTTP。
保持活动 -k
当客户端发送 HTTP 请求时,与服务器建立连接,服务器发送响应,并在发送请求后关闭连接。每个请求都会继续这个循环。但是,通过keep-alive设置(也称为持久连接),客户端保持一个底层TCP连接打开,以方便多个请求和响应;这消除了否则会出现的缓慢且昂贵的连接初始化时间。
可变文件长度 -l
如果网页的长度可变,那么您应该使用选项-l。如果响应的长度不固定,Apache Bench 不会报告错误。这对动态页面很有用。
使用选项 -r
如何强制 ab 在收到错误时不退出?您应该使用选项-r。如果没有这个选项,你的测试可能会在任何请求遇到套接字错误时立即中断。但是,使用此选项,将在失败的错误标题中报告错误,但测试将持续到结束。
使用选项 -H
此选项用于添加任意标题行。参数通常采用有效标题行的形式,包含以冒号分隔的字段值对(即“Accept-Encoding: zip/zop;8bit”)。
使用选项 -C
在下面的部分中,我们将详细学习如何结合使用cookie值的选项,即-C选项来使用上述选项。-C 选项通常采用名称 = 值对的形式。该字段可以重复。
在 Apache Bench 中使用会话 Cookie
要了解如何在 Apache Bench 中使用 cookie,我们需要一个尝试设置 cookie 的网页。一个很好的例子是 web2py 应用程序,它是一个 Python Web 框架。
安装 web2py
我们将快速安装另一个 python 应用程序 web2py。您可以在Web2py 框架概述中阅读有关如何使用它的更多信息。
Python 通常默认安装在 Ubuntu 和 Debian 服务器上。因此,成功运行 web2py 已经满足了一个要求。
但是,我们需要安装解压缩包以从我们将要下载的 zip 文件中提取 web2py 的源文件 –
$ sudo apt-get update $ sudo apt-get install unzip
让我们从项目的网站上获取 web2py 框架。我们将把它下载到我们的主文件夹 –
$cd ~ $ wget http://www.web2py.com/examples/static/web2py_src.zip
现在,我们可以解压缩刚刚下载的文件并移动到里面 –
$ unzip web2py_src.zip $ cd web2py
要运行 web2py,您不需要安装它。进入 web2py 目录后,您可以通过键入以下命令来运行它 –
$python web2py.py
如果一切顺利,您将看到以下输出,您将被要求为管理 UI 选择密码 –
web2py Web Framework Created by Massimo Di Pierro, Copyright 2007-2017 Version 2.14.6-stable+timestamp.2016.05.10.00.21.47 Database drivers available: sqlite3, imaplib, pymysql, pg8000 WARNING:web2py:GUI not available because Tk library is not installed choose a password: please visit: http://127.0.0.1:8000/ use "kill -SIGTERM 23904" to shutdown the web2py server
但是,您需要知道启动的 Web 界面只能在本地计算机上访问。
从输出中,您可以理解要停止 Web 服务器,您必须在即时终端中键入“CTRL-C”。另一方面,要停止与同一 VPS 相关的另一个终端上的 web2py 服务器,您可以插入命令 kill -SIGTERM <PID>,其中 <PID> 是 web2py 服务器的进程 ID,在这种情况下是23904。
来自 web2py 的会话 Cookie
如果页面只能由登录用户访问,不能从登录页面直接访问,在这种情况下,您可以使用-C标志。该标志为 ab 命令定义了一个 cookie。但是您必须从有效会话中获取会话标识符 cookie 的值。如何得到它?各种在线教程将指导您使用 Chrome(或 Mozilla)浏览器开发工具。但是在我们的测试案例中,由于应用程序只能在命令行上使用,我们将使用 lynx 浏览器来获取该值。
让我们先获取一个会话的 cookie 值。打开另一个终端并输入以下命令 –
$ lynx http://127.0.0.1:8000/
为响应上述命令,lynx 将询问您是否同意接受来自 web2py 服务器的 cookie,如下图所示。
在输入y以接受 cookie之前记下 cookie 值。现在终端将类似于下图 – 终端上的网站!
获得 cookie 值后,我们现在将运行 ab 测试。为此,我们将不得不打开第三个终端(见下图) –
现在,让我们在第三个终端中使用 -C 标志 –
$ ab -n 100 -c 10 -C session_name = 127.0.0.1-643dad04-3c34 http://127.0.0.1:8000/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: Rocket Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: / Document Length: 66 bytes Concurrency Level: 10 Time taken for tests: 0.051 seconds Complete requests: 100 Failed requests: 0 Non-2xx responses: 100 Total transferred: 27700 bytes HTML transferred: 6600 bytes Requests per second: 1968.12 [#/sec] (mean) Time per request: 5.081 [ms] (mean) Time per request: 0.508 [ms] (mean, across all concurrent requests) Transfer rate: 532.39 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 2 0.9 2 4 Processing: 0 3 0.9 3 5 Waiting: 0 2 1.1 2 4 Total: 4 5 0.7 5 7 Percentage of the requests served within a certain time (ms) 50% 5 66% 5 75% 5 80% 6 90% 6 95% 6 98% 7 99% 7 100% 7 (longest request)
从上面的输出中,我们注意到几点。首先,web2py 使用Rocket Web 服务器。我们还注意到,除了先前讨论的输出标题之外,我们还收到了“非 2xx 响应”。一般情况下,Http协议使用响应码来响应请求,200s范围内的任何事情都意味着’ok’,其余的对应一些问题。例如,400 是与资源相关的错误,例如 404 File Not Found。500s 对应于服务器错误。在我们的例子中,除了使用 -C 选项时,任何地方都没有错误。如前所述,可以使用 -l 选项来抑制它。
检查管理页面
在本节中,我们将了解如何检查管理页面。为了比较,让我们测试 web2py 应用程序的另一个 URL –
$ ab -n 100 -c 10 session_name = 127.0.0.1-643dad04-3c34 http://127.0.0.1:8000/admin
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: Rocket Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: /admin Document Length: 8840 bytes Concurrency Level: 10 Time taken for tests: 2.077 seconds Complete requests: 100 Failed requests: 0 Total transferred: 926700 bytes HTML transferred: 884000 bytes Requests per second: 48.14 [#/sec] (mean) Time per request: 207.749 [ms] (mean) Time per request: 20.775 [ms] (mean, across all concurrent requests) Transfer rate: 435.61 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 3.2 0 12 Processing: 62 204 52.2 199 400 Waiting: 61 203 52.0 199 400 Total: 62 205 54.3 199 411 Percentage of the requests served within a certain time (ms) 50% 199 66% 211 75% 220 80% 226 90% 264 95% 349 98% 381 99% 411 100% 411 (longest request)
您应该特别注意http://127.0.0.1:8000/和http://127.0.0.1:8000/admin 的“连接时间”和“服务请求的百分比……”部分中的相应统计数据。这是个很大的差异。
使用时间限制选项
通常,时间限制选项是一个棘手的选项。让我们从ab的手册中理解这一点,这是非常有解释性的 –
-t timelimit Maximum number of seconds to spend for benchmarking. This implies a -n 50000 internally. Use this to benchmark the server within a fixed total amount of time. Per default there is no timelimit.
让我们用这个选项运行一个测试。我们将在通过输出后记录我们的观察 –
$ ab -n 100 -c 10 -t 60 http://127.0.0.1:8000/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 5000 requests Completed 10000 requests Completed 15000 requests Completed 20000 requests Completed 25000 requests Completed 30000 requests Completed 35000 requests Completed 40000 requests Completed 45000 requests Completed 50000 requests Finished 50000 requests Server Software: Rocket Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: / Document Length: 66 bytes Concurrency Level: 10 Time taken for tests: 22.547 seconds Complete requests: 50000 Failed requests: 0 Non-2xx responses: 50000 Total transferred: 13850000 bytes HTML transferred: 3300000 bytes Requests per second: 2217.61 [#/sec] (mean) Time per request: 4.509 [ms] (mean) Time per request: 0.451 [ms] (mean, across all concurrent requests) Transfer rate: 599.88 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 2 0.8 2 8 Processing: 0 2 3.2 2 218 Waiting: 0 2 3.2 2 218 Total: 2 4 3.1 4 220 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 4 80% 5 90% 5 95% 5 98% 7 99% 8 100% 220 (longest request)
请注意,输出显示此选项会覆盖-n选项指定的请求数,并继续达到 50K 请求。然而,由于请求的处理速度非常快,ab 会在达到 50k 标记后立即终止——在本案例中,在 22 秒内(参见标题“测试时间”)。
您可以测试将http://127.0.0.1:8000/替换为http://127.0.0.1:8000/admin(假设它是我们的 web2py 应用程序)或第三方网站(如 https://www.apache)的相同命令.org/,注意统计数据的差异。
执行负载测试前的检查清单
有一些检查可以帮助您成功运行测试,并准确地测量性能。在执行负载测试之前考虑以下条件 –
-
确保没有加载额外的 python 模块。
-
为避免 TCP/IP 端口耗尽,您通常应等待 2-3 分钟,然后再进行另一项 ab 测试。
-
确保并发连接数低于 Apache Worker Threads。
-
如果 Apache 或 python 崩溃,您应该在执行另一个测试之前重新启动服务器。
动态页面的顺序测试用例
在本章中,我们将描述-n和-c的各种组合以及重要标志,以逐渐增加 Web 服务器的负载。
您应该主要关注以下指标如何随着负载的增加而变化 –
- 每秒请求数
- 连接时间(毫秒)
- 特定时间内服务请求的百分比(毫秒)
当服务器开始卡住并且您开始收到失败的请求时,您还应该注意阈值。
1 个并发用户执行 100 个页面点击
让我们由单个用户执行 100 个连续页面加载 –
$ ab -l -r -n 100 -c 1 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: Rocket Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: / Document Length: Variable Concurrency Level: 1 Time taken for tests: 0.045 seconds Complete requests: 100 Failed requests: 0 Non-2xx responses: 100 Keep-Alive requests: 0 Total transferred: 27700 bytes HTML transferred: 6600 bytes Requests per second: 2206.24 [#/sec] (mean) Time per request: 0.453 [ms] (mean) Time per request: 0.453 [ms] (mean, across all concurrent requests) Transfer rate: 596.80 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 0 0.0 0 0 Waiting: 0 0 0.0 0 0 Total: 0 0 0.0 0 1 Percentage of the requests served within a certain time (ms) 50% 0 66% 0 75% 0 80% 0 90% 1 95% 1 98% 1 99% 1 100% 1 (longest request)
5 个并发用户,每个用户执行 10 次页面点击
这种情况对应于网站上的峰值负载,每月点击量超过 50,000 次。
$ ab -l -r -n 10 -c 5 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
在以下后续输出中,为了清晰起见,我们将省略通用标题。
输出
... Requests per second: 2009.24 [#/sec] (mean) Time per request: 2.488 [ms] (mean) Time per request: 0.498 [ms] (mean, across all concurrent requests) Transfer rate: 543.52 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.5 1 2 Processing: 0 1 0.5 1 2 Waiting: 0 1 0.5 1 1 Total: 2 2 0.4 3 3 ERROR: The median and mean for the total time are more than twice the standard deviation apart. These results are NOT reliable. Percentage of the requests served within a certain time (ms) 50% 3 66% 3 75% 3 80% 3 90% 3 95% 3 98% 3 99% 3 100% 3 (longest request)
10 个并发用户,每个用户点击 10 次页面
此测试对应 10 个不同并发用户加载 100 个页面,每个用户执行 10 个连续页面加载。
$ ab -r -n 10 -c 10 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
输出
... Requests per second: 2225.68 [#/sec] (mean) Time per request: 4.493 [ms] (mean) Time per request: 0.449 [ms] (mean, across all concurrent requests) Transfer rate: 602.07 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 2 0.7 2 3 Processing: 0 2 1.0 2 3 Waiting: 0 1 1.0 2 3 Total: 4 4 0.3 4 4 WARNING: The median and mean for the waiting time are not within a normal deviation These results are probably not that reliable. Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 4 80% 4 90% 4 95% 4 98% 4 99% 4 100% 4 (longest request)
20 个并发用户,每个用户进行 20 次页面点击
此测试对应 20 个不同并发用户加载 400 个页面,每个用户执行 20 个连续页面加载。
$ ab -r -n 20 -c 20 -k -H “Accept-Encoding: gzip, deflate” http://127.0.0.1:8000/
输出
... Requests per second: 1619.96 [#/sec] (mean) Time per request: 12.346 [ms] (mean) Time per request: 0.617 [ms] (mean, across all concurrent requests) Transfer rate: 438.21 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 2 6 2.3 6 10 Processing: 1 5 2.9 5 10 Waiting: 0 5 2.9 5 9 Total: 10 11 0.6 11 12 Percentage of the requests served within a certain time (ms) 50% 11 66% 11 75% 12 80% 12 90% 12 95% 12 98% 12 99% 12 100% 12 (longest request)
30 个并发用户,每个用户点击 30 次页面
此测试对应 30 个不同并发用户加载 900 个页面,每个用户执行 30 个连续页面加载。
$ ab -r -n 30 -c 30 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
输出
... Requests per second: 2283.45 [#/sec] (mean) Time per request: 13.138 [ms] (mean) Time per request: 0.438 [ms] (mean, across all concurrent requests) Transfer rate: 617.69 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 2 6 2.7 6 11 Processing: 1 6 3.1 6 11 Waiting: 0 5 3.2 5 10 Total: 11 12 0.5 12 13 Percentage of the requests served within a certain time (ms) 50% 12 66% 12 75% 12 80% 12 90% 13 95% 13 98% 13 99% 13 100% 13 (longest request)
我们现在已经学会了如何逐渐增加网站的负载并测试其性能。
Apache Bench – 输出比较
在本章中,我们将比较带有和不带有标志的输出。让我们看看使用适当的标志如何提高 Web 应用程序的性能。在此之前,我们需要了解如果您的应用程序很简单,那么您可能不会注意到差异。就像我们的简单应用程序一样,有标志和没有标志。然后我们将使用https://www.apache.org/ URL执行相同的测试,并查看不同之处。
在没有标志的情况下测试我们的应用程序
在本节中,我们将了解如何在没有标志的情况下测试我们的应用程序。
$ ab -n 100 -c 10 http://127.0.0.1:8000/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: Rocket Server Hostname: 127.0.0.1 Server Port: 8000 Document Path: / Document Length: Variable Concurrency Level: 10 Time taken for tests: 0.244 seconds Complete requests: 100 Failed requests: 0 Non-2xx responses: 100 Keep-Alive requests: 0 Total transferred: 27700 bytes HTML transferred: 6600 bytes Requests per second: 2208.77 [#/sec] (mean) Time per request: 4.527 [ms] (mean) Time per request: 0.453 [ms] (mean, across all concurrent requests) Transfer rate: 597.49 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 2 0.7 2 3 Processing: 0 2 0.7 2 4 Waiting: 0 2 1.0 2 3 Total: 4 4 0.3 4 5 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 5 80% 5 90% 5 95% 5 98% 5 99% 5 100% 5 (longest request)
使用标志测试我们的应用程序
在本节中,我们将了解如何使用标志测试我们的应用程序。
$ ab -l -r -n 100 -c 10 -k -H "Accept-Encoding: gzip, deflate" http://127.0.0.1:8000/
输出
... Requests per second: 2277.07 [#/sec] (mean) Time per request: 4.392 [ms] (mean) Time per request: 0.439 [ms] (mean, across all concurrent requests) Transfer rate: 615.97 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 2 0.7 2 3 Processing: 0 2 0.7 2 4 Waiting: 0 2 1.0 2 3 Total: 4 4 0.2 4 5 Percentage of the requests served within a certain time (ms) 50% 4 66% 4 75% 4 80% 4 90% 5 95% 5 98% 5 99% 5 100% 5 (longest request)
我们可以简单地注意到,输出统计数据之间没有太大差异。
无标志测试 Apache 组织网站
现在让我们看看如何在没有标志的情况下测试 Apache 组织网站。
$ ab -n 100 -c 10 http://www.apache.org/
输出
This is ApacheBench, Version 2.3 <$Revision: 1604373 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.apache.org (be patient).....done Server Software: Apache/2.4.7 Server Hostname: www.apache.org Server Port: 80 Document Path: / Document Length: 58433 bytes Concurrency Level: 10 Time taken for tests: 1.498 seconds Complete requests: 100 Failed requests: 0 Total transferred: 5877500 bytes HTML transferred: 5843300 bytes Requests per second: 66.74 [#/sec] (mean) Time per request: 149.840 [ms] (mean) Time per request: 14.984 [ms] (mean, across all concurrent requests) Transfer rate: 3830.58 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 12 110 295.2 12 1012 Processing: 37 38 0.5 38 39 Waiting: 12 13 0.3 13 15 Total: 49 147 295.4 50 1051 Percentage of the requests served within a certain time (ms) 50% 50 66% 50 75% 50 80% 50 90% 816 95% 1050 98% 1051 99% 1051 100% 1051 (longest request)
使用标志测试 Apache 组织网站
现在让我们用标志测试 Apache 组织网站。
$ ab -l -r -n 100 -c 10 -k -H "Accept-Encoding: gzip, deflate" http://www.apache.org/
输出
... Document Length: Variable Concurrency Level: 10 Time taken for tests: 0.357 seconds Complete requests: 100 Failed requests: 0 Keep-Alive requests: 100 Total transferred: 1358510 bytes HTML transferred: 1317700 bytes Requests per second: 280.28 [#/sec] (mean) Time per request: 35.678 [ms] (mean) Time per request: 3.568 [ms] (mean, across all concurrent requests) Transfer rate: 3718.41 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 3.7 0 12 Processing: 14 17 21.3 15 227 Waiting: 14 17 21.3 14 227 Total: 14 18 21.5 15 227 Percentage of the requests served within a certain time (ms) 50% 15 66% 15 75% 15 80% 15 90% 27 95% 28 98% 29 99% 227 100% 227 (longest request)
您可以简单地注意每秒请求如何随着标志的使用而增加。在这种情况下,特别是由于使用了-H “Accept-Encoding: gzip , deflate ,因为这个标志告诉 Apache 服务器以gzipped格式提供请求。
考虑 Apache Bench 结果
当涉及到 Apache Bench 结果时,需要考虑几个要点。这将帮助我们设计整体策略以消除应用程序中的瓶颈并提高其性能。
我们需要每秒请求数。这让我们了解我们的网络服务器设置的工作情况;数字越大,性能越好。然后是连接时间 (ms) 和服务请求的百分比。您可能需要调整 Web 服务器的设置以将这些指标更改为您想要的性能。
检查 Apache 或使用的 Web 服务器错误日志或(一般)日志中是否存在错误。当您增加负载时,事情将开始变得困难:内存问题将开始出现。如果编写时没有考虑到并发性,许多 python 脚本将开始崩溃。
您需要找出您的 Web 服务器崩溃和/或超时的临界并发值是多少?通常这应该发生在相当高的并发级别。如果此值较低,则说明有问题,您需要将这些设置调低/调高。
结论
在本教程中,我们学习了如何使用 Apache Bench 对任何网站或 Web 应用程序进行负载测试。Apache Bench 是一个非常有价值的工具,用于确定应如何改进您的 Web 应用程序服务器设置,以减少瓶颈并提高性能。现在您已经熟悉了 Apache Bench 的基本用法,您可以开始创建新的测试计划来衡量您的应用程序在各种场景中的性能。