压力测试是软件开发不可或缺的一部分,因为它有助于确保应用程序能够处理极端情况和负载的意外波动。通过将软件推到正常运行能力之外,压力测试可以识别潜在的瓶颈、漏洞和弱点,这些都可能在现实压力下导致系统故障。这种积极主动的方法不仅增强了软件的稳定性和性能,而且即使是在最苛刻的情况下,也能建立其能提供持续稳定用户体验的能力的信心。
今天,将演示3个可以帮助我们完成工作的开源工具。
HEY
Hey 是一个很小的程序,它向 Web 应用程序发送一些模拟请求。它最初是用 Go 编写的,但似乎没有得到积极的维护。因此,从最初的 git 存储库构建和使用它可能有点过时。不过我们不需要关注如何安装 Go,或者更新/升级它来完成工作。因为我们关注的是压力测试,而不是给自己施加压力修复它。因此,可以在 Docker hub 上使用 ahmadalsajid/hey-Docker,这是一个基于 Alpine 的 Docker 镜像,具有与最新版本 Go 构建的原始 hey 的准确特征。它是为 Linux/amd64和 Linux/amd64架构构建的,大小仍然低于20MB。如果你已经在计算机上安装了 docker,那么只需使用 hey 命令即可。命令的基本用法是
docker run --rm ahmadalsajid/hey-docker -n 200 -c 50 https://www.apache.org/
下面是运行结果:
Summary:
Total: 31.8439 secs
Slowest: 20.0013 secs
Fastest: 0.1656 secs
Average: 5.3480 secs
Requests/sec: 6.2806
Response time histogram:
0.166 [1] |■
2.149 [64] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
4.133 [33] |■■■■■■■■■■■■■■■■■■■■■
6.116 [39] |■■■■■■■■■■■■■■■■■■■■■■■■
8.100 [14] |■■■■■■■■■
10.083 [13] |■■■■■■■■
12.067 [18] |■■■■■■■■■■■
14.051 [4] |■■■
16.034 [7] |■■■■
18.018 [1] |■
20.001 [6] |■■■■
Latency distribution:
10% in 0.6372 secs
25% in 1.4959 secs
50% in 4.1704 secs
75% in 7.7139 secs
90% in 11.2524 secs
95% in 14.5390 secs
99% in 20.0011 secs
Details (average, fastest, slowest):
DNS+dialup: 0.5441 secs, 0.0000 secs, 9.5668 secs
DNS-lookup: 0.5648 secs, 0.0000 secs, 2.2529 secs
req write: 0.0001 secs, 0.0000 secs, 0.0010 secs
resp wait: 0.8579 secs, 0.0642 secs, 6.8206 secs
resp read: 2.1870 secs, 0.0005 secs, 14.9386 secs
Status code distribution:
[200] 200 responses
可供选择的选项有:
选项:
-n 要运行的请求数。默认值为200。
-c 并发运行数。请求总数不能小于并发级别。默认值为50。-q 速率限制,以每个线程每秒查询(QPS)数为单位。默认为没有速率限制。
-z 发送请求的应用程序持续时间。当持续时间达到设定值时,应用程序停止并且退出。如果指定了持续时间,则忽略 n。
示例:-z 10s -z 3m。
-o Output 类型。如果没有提供,则打印摘要。“ csv”是唯一受支持的替代方案。转储响应逗号作为分隔值格式的指标。
-m HTTP 方法,GET、 POST、 PUT、 DELETE、 HEAD、 OPTION 之一。
-H 自定义 HTTP 头。可以通过重复标志来指定所需的数量。
示例:-H“ Accept: text/html”-H“ Content-Type: application/xml”。-t 每个请求的超时时间(以秒为单位)。默认值为20,使用0代表不限时。
-A HTTP Accept 头。
-d HTTP 请求正文。
-D HTTP 请求正文来自文件,例如/home/user/file.txt 或./file.txt。
-T Content-type,默认值是“ text/html”。
-a 基础认证,用户名: 密码。
-x HTTP 代理地址作为主机: 端口。
-h2 启用 HTTP/2。-host HTTP host请求头。
-disable-compression 禁用压缩。
-disable-keepalive 禁用keep-alive
,防止重用 TCP
不同 HTTP 请求之间的连接。
-disable-redirects 禁止跟踪 HTTP 重定向
-cpus 中央处理器使用过的中央处理器核心数目。(当前机器的默认值是8核)
OHA
正如我们前面所说的,HEY没有被主动监视,OHA 的灵感来自 HEY,但是是用 Rust 编写的。这也引发了同样的问题,如果你不熟悉 Rust,它会让你的生活再次变得悲惨。我们关注的是压力测试,而不是给自己施加压力修复它。这就是为什么ahmadalsajid/oha-docker 中提供了另一个多架构、轻量级的 oha docker快照。你只需要将快照从git上拉下来,并将其作为容器运行。
docker pull ahmadalsajid/oha-docker
docker run --rm -it ahmadalsajid/oha-docker -n 200 -c 50 https://www.apache.org/
你会看到一个漂亮的用户界面,像这样的
图片来自 https://github.com/hatoo/oha/blob/master/demo.gif
一旦完成,你将在控制台中得到结果。
Summary:
Success rate: 100.00%
Total: 7.2522 secs
Slowest: 7.2513 secs
Fastest: 0.1388 secs
Average: 1.2849 secs
Requests/sec: 27.5779
Total data: 3.03 MiB
Size/request: 15.49 KiB
Size/sec: 427.16 KiB
Response time histogram:
0.139 [1] |
0.850 [92] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1.561 [58] |■■■■■■■■■■■■■■■■■■■■
2.273 [17] |■■■■■
2.984 [17] |■■■■■
3.695 [6] |■■
4.406 [4] |■
5.118 [1] |
5.829 [0] |
6.540 [1] |
7.251 [3] |■
Response time distribution:
10.00% in 0.3168 secs
25.00% in 0.5857 secs
50.00% in 0.9099 secs
75.00% in 1.5029 secs
90.00% in 2.6671 secs
95.00% in 3.5923 secs
99.00% in 7.0764 secs
99.90% in 7.2513 secs
99.99% in 7.2513 secs
Details (average, fastest, slowest):
DNS+dialup: 0.8507 secs, 0.1761 secs, 2.6988 secs
DNS-lookup: 0.0003 secs, 0.0000 secs, 0.0051 secs
Status code distribution:
[200] 200 responses
输入选项与 HEY 非常相似,只是-q 有一点不同,该选项的工作方式与 hey 不同。它每秒为全部的请求设置请求,而不是为每个线程设置请求。其他选项是
Options:
-n <N_REQUESTS> 要运行的请求数。[默认值: 200]
-c <N_CONNECTIONS> 要并发运行的连接数。你可能会增加打开文件的数量限制,以适应较大的“-c”。[默认值: 50]
-p <N_HTTP2_PARALLEL> 在 HTTP/2上发送的并行请求数。“ oha”将运行 c * p 并发工人总数。[默认值: 1]
-z <DURATION> 发送请求的申请持续时间。如果指定了持续时间,则忽略 n。
当持续时间到结束时间时,正在进行的请求将被中止,并被视为“由于最后期限而中止”
示例: -z 10s -z 3m.
-q <QUERY_PER_SECOND> 以每秒查询(QPS)为单位的全部速率限制
--burst-delay <BURST_DURATION> 预定义数量的请求之间引入延迟。
注意: 如果指定了 qps,将忽略突发请求
--burst-rate <BURST_REQUESTS> 突发请求速率。默认值为1
注意: 如果指定了 qps,将忽略突发请求
--rand-regex-url 使用 rand _ regex crate 生成 URL,但对于每个查询都禁用 dot,例如 http://127.0.0.1/[ a-z ][ a-z ][0-9]。目前的动态方案、主机和保持活动的端口都不能很好地工作。Https://docs.rs/rand_regex/latest/rand_regex/struct.有关语法的详细信息,请参阅 Regex.html。
--max-repeat <MAX_REPEAT> “—— rand-regex-url”的参数。Max _ repeat 参数给出 x * 、 x + 和 x { n,}运算符将变成的最大额外重复计数。[默认值: 4]
--latency-correction 纠正延迟以避免协调遗漏问题,如果未设置-q,则忽略。
--no-tui 非实时的tui
-j, --json 将结果打印为 JSON
--fps <FPS> tui 的每秒帧数。[默认值: 16]
-m, --method <METHOD> HTTP 方法 [默认值: GET]
-H <HEADERS> 自定义 HTTP 头。示例:-H“ foo: bar”
-t <TIMEOUT> 每个请求的超时。默认为无穷大。
-A <ACCEPT_HEADER> HTTP Accept Header.
-d <BODY_STRING> HTTP request body.
-D <BODY_PATH> HTTP 来自文件的request body.
-T <CONTENT_TYPE> Content-Type.
-a <BASIC_AUTH> 基础身份验证,用户名: 密码
--http-version <HTTP_VERSION> HTTP 版本。可用值为0.9,1.0,1.1。
--http2 使用 HTTP/2。简称—— http-version = 2
--host <HOST> HTTP Host header
--disable-compression 禁用压缩。
-r, --redirect <REDIRECT> 重定向的数量限制。如果没有重定向,则设置为0。重定向不支持HTTP/2. [默认值: 10]
--disable-keepalive 禁用keep-alive,防止在不同 HTTP 请求之间重用 TCP 连接。这不支持HTTP/2.
--no-pre-lookup 不在开始缓存DNS时执行 DNS 查找。
--ipv6 仅查找ipv6。
--ipv4 仅查找ipv4。
--insecure 接受无效证书。
--connect-to <CONNECT_TO> 覆盖 DNS 解析和默认端口号,使用字符串如’’example.org:443:localhost:8443Example.org: 443: localhost: 8443
--disable-color 禁用配色方案。
--unix-socket <UNIX_SOCKET> 连接到一个 unix 套接字,而不是 URL 中的域。只适用于非 HTTPS URL。
--vsock-addr <VSOCK_ADDR> 使用’cid:port',而不是 URL 中的域。只适用于非 HTTPS URL。
--stats-success-breakdown 包括一个响应状态代码成功或不成功的时间直方图和分布统计细分
-h, --help 打印帮助
-V, --version 打印版本
Apache Benchmark(ab)
最后一个,ApacheBenchmark。它也是一个 CLI 工具。先安装一下,
在 Ubuntu 上
sudo apt install apache2-utils -y
在Mac上
在 macos bigsur 和更高版本中,ab 默认安装在 macos 中
在Windows上
从 here. unzip 下载 Apache 二进制文件,然后从解压缩/安装它的地方运行 ab
~\Apache24\bin>ab -n 100 -c 10 xxx
最简单的测试方法如下
ab -n 200 -c 50 -r https://www.apache.org/
我们可以看到结果是
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
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)
Completed 100 requests
Completed 200 requests
Finished 200 requests
Server Software: Apache
Server Hostname: www.apache.org
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,2048,256
Server Temp Key: X25519 253 bits
TLS Server Name: www.apache.org
Document Path: /
Document Length: 64380 bytes
Concurrency Level: 50
Time taken for tests: 27.800 seconds
Complete requests: 200
Failed requests: 0
Total transferred: 13086332 bytes
HTML transferred: 12876000 bytes
Requests per second: 7.19 [#/sec] (mean)
Time per request: 6950.095 [ms] (mean)
Time per request: 139.002 [ms] (mean, across all concurrent requests)
Transfer rate: 459.69 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 229 1340 1402.3 888 8962
Processing: 197 3003 2978.5 2142 22173
Waiting: 67 247 308.1 101 1883
Total: 437 4343 3605.0 3539 24386
Percentage of the requests served within a certain time (ms)
50% 3539
66% 5194
75% 5940
80% 6362
90% 7851
95% 9867
98% 18300
99% 21180
100% 24386 (longest request)
接下来就能操作查看AB的选项了:
ab -help
你会得到用法和选项:
用法: ab [options] [http[s]://]hostname[:port]/path
选项有:
-n requests 要执行的请求数
-c concurrency 一次要发出的多个请求的数目
-t timelimit 限制基准最大到秒。
这意味着 -n 50000
-s timeout 最大到秒. 等待每个响应
默认是30 seconds
-b windowsize TCP 发送/接收缓冲区的大小,以字节为单位
-B address 当进行外部连接时要绑定到的地址
-p postfile 包含 POST 请求数据的文件。记住还要设置-T
-u putfile 包含 PUT 请求数据的文件. 记住还要设置-T
-T content-type 用于POST/PUT 数据的Content-type,例如:'application/x-www-form-urlencoded'
默认值是'text/plain'
-v verbosity 要打印多少故障排除信息
-w 以 HTML 表格列印结果
-i 用 HEAD 代替 GET
-x attributes 作为表属性插入的字符串
-y attributes 作为 tr 属性插入的字符串
-z attributes 作为 td 属性插入的字符串
-C attribute 添加 cookie,例如‘ Apache = 1234’。(可重复)
-H attribute 添加任意请求头,例如:'Accept-Encoding: gzip'
插入在所有正常的请求头之后
-A attribute 添加基础的 WWW 身份验证,这个属性是用冒号分隔的用户名和密码。
-P attribute 属性添加基本代理身份验证,这个属性是用冒号分隔的用户名和密码。
-X proxy:port 代理服务器和要使用的端口号。
-V 打印版本号并退出。
-k 使用 HTTP KeepAlive 功能。
-d 不显示百分位数服务表。
-S 不要显示信心估计和警告。
-q 在处理超过150项请求时不显示进展情况。
-l 接受可变文档长度(用于动态页面)
-g filename 将收集到的数据输出为 gnuplot 格式文件。
-e filename 输出包含所提供的百分比的CSV文件
-r 不退出套接字接收错误。
-m method 方法名称
-h 显示使用信息(此信息)
-I 关闭 TLS 服务器名称指示(SNI)分机
-Z ciphersuite 指定 SSL/TLS 密码套件(见 openssl 密码)
-f protocol 指定 SSL/TLS 协议(SSL2、 TLS1、 TLS1.1、 TLS1.2或 ALL)
-E certfile 指定可选的客户端证书链和私钥
结论
尽管上面讨论的只代表了大量开源选项中可用于压力测试的一小部分工具,但是它们因其易用性和有效性而脱颖而出。探索各种工具可能是有价值的,但是这些特殊的工具为寻求增强软件弹性的开发团队提供了坚实的基础。它们的可访问性和健壮特性使它们成为将压力测试集成到开发过程中的一个极好的起点,确保应用程序准备好满足实际使用的需求。