ab 测试

Apache Benchmark Tool

ab is a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server. It is designed to give you an impression of how your current Apache installation performs. This especially shows you how many requests per second your Apache installation is capable of serving.

ab 是 apache http server 基准测试工具,它可以帮助我们去了解当前服务的表现,如每秒请求数等。下面是 ab 对应的所有 options 摘要信息:

1
2
3
4
5
6
7
8
ab [ -A auth-username:password ] [ -b windowsize ] [ -B local-address ] [ -c 
concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -E client-certificate
file ] [ -f protocol ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [
-l ] [ -m HTTP-method ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-
username:password ] [ -q ] [ -r ] [ -s timeout ] [ -S ] [ -t timelimit ] [ -T content-
type ] [ -u PUT-file ] [ -v verbosity] [ -V ] [ -w ] [ -x <table>-attributes ] [ -X
proxy[:port] ] [ -y <tr>-attributes ] [ -z <td>-attributes ] [ -Z ciphersuite ]
[http[s]://]hostname[:port]/path

下面是各参数的解释

options keys exlpain
-A auth-username : password 向服务器提供 BASIC 身份验证凭据。用户名和密码由一个:分隔,并通过 wire base64编 码发送。无论服务器是否需要该字符串(即,是否发送了 401 身份验证),都将发送该字符串。
-b windowsize TCP发送/接收缓冲区大小,以字节为单位。
-B local-address 进行传出连接时要绑定的地址。
-c concurrency 单次执行的并发 request 数量,默认一次执行一个请求
-C cookie-name = value 给请求添加 Cookie
-d Do not display the “percentage served within XX [ms] table”. (legacy support).不重要
-e csv-file 编写一个逗号分隔值 (CSV) 文件,其中包含每个百分比(从 1% 到 100%)处理该百分比请求所需的时间(以毫秒为单位)。这通常比“gnuplot”文件更有用;因为结果已经被“装箱”了。
-E client-certificate-file 连接到 SSL 网站时,使用提供的 PEM 格式的客户端证书向服务器进行身份验证。该文件应包含客户端证书,然后是中间证书,然后是私钥。在 2.4.36 及更高版本中可用。
-f protocol 指定 SSL/TLS 协议(SSL2、SSL3、TLS1、TLS1.1、TLS1.2 或 ALL)。 TLS1.1 和 TLS1.2 支持在 2.4.4 及更高版本中可用。
-H custom-header 支持添加额外的 headers 到 request ;如 “Accept-Encoding: zip/zop;8bit”
-i 执行 HEAD 请求而不是 GET 请求。
-k 开启 http keep-alive 特性,比如在一个 HTTP会话中执行多个请求。默认为无 KeepAlive。
-m HTTP-method 自定义 http method,2.4.10 之后版本可用
-n requests 基准测试会话执行的请求数。默认情况下只执行单个请求,这通常会导致不具有代表性的基准测试结果。
-p POST-file 包含要POST数据的文件。记住还要设置-T。
-P proxy-auth-username : password 在途中向代理提供BASIC身份验证凭据。用户名和密码由一个:分隔,并通过 wire base64编码发送。无论代理是否需要该字符串(即,是否发送了需要的407代理身份验证),都将发送该字符串。
-q 当处理超过150个请求时,ab每10%或大约100个请求输出一个stderr进度计数。-q标志将抑制这些消息。
-r 不要在套接字接收错误时退出。
-s timeout 在套接字超时之前等待的最大秒数。默认为30秒。在2.4.4及以后版本中可用。
-S 不要显示中值和标准偏差值,也不要在平均值和中值相差超过标准偏差的一倍或两倍时显示警告/错误消息。默认为min/avg/max值。(遗留支持)
-t timelimit 用于基准测试的最大秒数。这在内部意味着-n 50000。使用它可以在固定的总时间内对服务器进行基准测试。默认情况下没有时间限制。
-T content-type 用于 POST/PUT 数据 数据的内容类型标头;如application/x-www-form-urlencoded. 默认 text/plain
-u PUT-file 包含要PUT的数据的文件。记住还要设置-T。
-v verbosity 设置详细级别- 4及以上将打印标题信息,3及以上将打印响应代码(404、200等),2及以上将打印警告和信息。

使用 ab 进行测试

下面是一个非常简单的 api 代码,启动 web server 之后通过 http://localhost:8080/api/test 即可请求。

1
2
3
4
5
6
7
8
9
10
@RestController
@RequestMapping("api")
public class PressureService {

@RequestMapping("test")
public String test() throws InterruptedException {
Thread.sleep(3000);
return "abc" + new String("bcd");
}
}

执行如下命令 ab -n 200 -c 100 http://localhost:8080/api/test;总共发送 200 个请求,每次请求并发 100,得到的结果如下:

1
2
3
4
5
6
7
➜  ~ ab -n 200 -c 100  http://localhost:8080/api/test
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 localhost (be patient)
apr_pollset_poll: The timeout specified has expired (70007)

可以看到这里没有得到正常的测试反馈结果;报了 apr_pollset_poll: The timeout specified has expired (70007);出现这个 maessage 的原因是 timeout 连接超时了。 通过上面那个表中的 options 来看,可以通过加 -k 和 -s 来分别指定 下 keep-alive 和 超时时间,也可以通过 -r 来规避遇到socket接收错误后,不退出测试。

使用 -k 和 -s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
➜  ~ ab -n 200 -c 10 -s 5000 -k  http://localhost:8080/api/test
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 localhost (be patient)
Completed 100 requests
Completed 200 requests
Finished 200 requests


Server Software:
Server Hostname: localhost
Server Port: 8080

Document Path: /api/test
Document Length: 6 bytes

Concurrency Level: 10
Time taken for tests: 352.210 seconds
Complete requests: 200
Failed requests: 8
(Connect: 0, Receive: 0, Length: 8, Exceptions: 0)
Keep-Alive requests: 192
Total transferred: 27840 bytes
HTML transferred: 1152 bytes
Requests per second: 0.57 [#/sec] (mean)
Time per request: 17610.485 [ms] (mean)
Time per request: 1761.049 [ms] (mean, across all concurrent requests)
Transfer rate: 0.08 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 3002 15972 44971.8 3006 218613
Waiting: 0 11492 40519.5 3006 218613
Total: 3002 15972 44971.9 3006 218613

Percentage of the requests served within a certain time (ms)
50% 3006
66% 3006
75% 3007
80% 3007
90% 3008
95% 112001
98% 209597
99% 215607
100% 218613 (longest request)

使用 -r

在不适用 -r 的请求下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
➜  ~ ab -n 200 -c 100 -s 5000 -k -r  http://localhost:8080/api/test
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 localhost (be patient)
Completed 100 requests
Completed 200 requests
Finished 200 requests


Server Software:
Server Hostname: localhost
Server Port: 8080

Document Path: /api/test
Document Length: 6 bytes

Concurrency Level: 100
Time taken for tests: 107.100 seconds
Complete requests: 200
Failed requests: 147
(Connect: 0, Receive: 0, Length: 147, Exceptions: 0)
Keep-Alive requests: 53
Total transferred: 7685 bytes
HTML transferred: 318 bytes
Requests per second: 1.87 [#/sec] (mean)
Time per request: 53549.816 [ms] (mean)
Time per request: 535.498 [ms] (mean, across all concurrent requests)
Transfer rate: 0.07 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 2.1 3 8
Processing: 3002 43074 19044.3 49998 75116
Waiting: 0 5502 15736.0 0 75116
Total: 3002 43077 19045.5 50002 75117

Percentage of the requests served within a certain time (ms)
50% 50002
66% 50003
75% 54088
80% 54089
90% 54090
95% 54092
98% 66104
99% 72112
100% 75117 (longest request)

Connection reset by peer

1
2
3
4
5
6
7
➜  ~ ab -n 200 -c 100 -s 5000 -k  http://localhost:8080/api/test
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 localhost (be patient)
apr_socket_recv: Connection reset by peer (54)

Connection reset by peer也会导致 ab 中途退出,从本地测试来看,当并发数增加时,出现该问题的比率会增加;Connection Reset by peer 意味着远端终止了会话,即当操作系统接收到远端服务器的RST (TCP Reset)通知时会产生此错误。在使用 ab 时,可以通过 -r 来忽略这种错误,在遇到socket接收错误后,不退出测试。

ab 的结果解析

版本相关

1
2
3
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/

这部分信息是 ab 的版本信息,可以忽略。

测试完成度

1
2
3
4
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Finished 200 requests

以上内容显示测试完成度,通过分行显示当前完成数量。

测试服务器信息

1
2
3
Server Software:
Server Hostname: localhost
Server Port: 8080

Server Software 一栏没有数据,因为本地启动的 server 容器;其他两个就是地址和端口。

地址和包大小

1
2
Document Path:          /api/test
Document Length: 6 bytes

测试数据详情

1
2
3
4
5
6
7
8
9
10
11
12
Concurrency Level:      100
Time taken for tests: 107.100 seconds
Complete requests: 200
Failed requests: 147
(Connect: 0, Receive: 0, Length: 147, Exceptions: 0)
Keep-Alive requests: 53
Total transferred: 7685 bytes
HTML transferred: 318 bytes
Requests per second: 1.87 [#/sec] (mean)
Time per request: 53549.816 [ms] (mean)
Time per request: 535.498 [ms] (mean, across all concurrent requests)
Transfer rate: 0.07 [Kbytes/sec] received
  • Concurrency Level:并发数,-c 参数值
  • Time taken for tests:本次测试总共花费的时间
  • Complete requests:本次请求执行的请求数总量
  • Failed requests:失败的请求数量。因网络原因或服务器性能原因,发起的请求并不一定全部成功,通过该数值和Complete requests相除可以计算请求的失败率,作为测试结果的重要参考。
  • Keep-Alive requests:使用长连接的请求数量
  • Total transferred:总共传输的数据量,指的是 ab 从被测服务器接收到的总数据量,包括文本内容和请求头信息。
  • HTML transferred:从服务器接收到的 html 文件的总大小,等于 Document Length*Complete requests
  • Requests per second:平均每秒完成的请求数:QPS,是一个平均值,等于 Complete requests/Time taken for tests
  • Time per request:从用户角度看,完成一个请求所需要的时间(因用户数量不止一个,服务器完成 10 个请求,平均每个用户才接收到一个完整的返回,所以该值是下一项数值的10倍。)
  • Time per request:服务器完成一个请求的时间。
  • Transfer rate:网络传输速度,对于大文件的请求测试,这个值很容易成为系统瓶颈所在。要确定该值是不是瓶颈,需要了解客户端和被测服务器之间的网络情况,包括网络带宽和网卡速度等信息。

Time per request 统计信息

1
2
3
4
5
6
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 2.1 3 8
Processing: 3002 43074 19044.3 49998 75116
Waiting: 0 5502 15736.0 0 75116
Total: 3002 43077 19045.5 50002 75117

对上面第一个 Time per request 进行细分和统计。一个请求的响应时间可以分成网络链接(Connect),系统处理(Processing)和等待(Waiting)三个部分。表中 min 表示最小值; mean 表示平均值;[+/-sd] 表示标准差(Standard Deviation) ,也称均方差(mean square error),该数值越大表示数据越分散,系统响应时间越不稳定。 median 表示中位数; max 当表示最大值。

Total 是从整个请求所需要的时间的角度来统计的。这里可以看到最慢的一个请求花费了 75117 ms,这个数据可以在下面的表中得到验证。

1
2
3
4
5
6
7
8
9
10
Percentage of the requests served within a certain time (ms)
50% 50002
66% 50003
75% 54088
80% 54089
90% 54090
95% 54092
98% 66104
99% 72112
100% 75117 (longest request)

这个表第一行表示有 50% 的请求都是在 50002 ms 内完成的,这个值是比较接近平均系统响应时间(第一个 Time per request: 53549.816 ms ); 以此类推。

前面看到响应时间最长的那个请求是 75117 ms,那么显然所有请求(100%)的时间都是小于等于 75117 ms 的,也就是表中最后一行的数据就是时间最长的那个请求(longest request)。

参考

作者

卫恒

发布于

2022-09-22

更新于

2022-09-22

许可协议

评论