跳至主要內容

ab压力测试工具使用详解

zhengcog...大约 12 分钟博文压力测试性能测试ab工具

工具介绍

Apache Benchmark(简称ab) 是Apache安装包中自带的压力测试工具 ,简单易用。

命令参数

ab -help

Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
                    This implies -n 50000
    -s timeout      Seconds to max. wait for each response
                    Default is 30 seconds
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -B address      Address to bind to when making outgoing connections
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header to use for POST/PUT data, eg.
                    'application/x-www-form-urlencoded'
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234'. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -q              Do not show progress when doing more than 150 requests
    -l              Accept variable document length (use this for dynamic pages)
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -m method       Method name
    -h              Display usage information (this message)
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol
                    (TLS1, TLS1.1, TLS1.2 or ALL)

参数解释

-n 即requests,用于指定压力测试总共的请求次数。
-c 即concurrency,用于指定的并发数。
-t 即timelimit,等待响应的最大时间(单位:秒)。
-b 即windowsize,TCP发送/接收的缓冲大小(单位:字节)。
-p 即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数。
-u 即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数。
-T 即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain。
-v 即verbosity,指定打印帮助信息的冗余级别。
-w 以HTML表格形式打印结果。
-i 使用HEAD请求代替GET请求。
-x 插入字符串作为table标签的属性。
-y 插入字符串作为tr标签的属性。
-z 插入字符串作为td标签的属性。
-C 添加cookie信息,例如:"Apache=1234"(可以重复该参数选项以添加多个)。
-H 添加任意的请求头,例如:"Accept-Encoding: gzip",请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)。
-A 添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开。
-P 添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开。
-X 指定使用的和端口号,例如:"126.10.10.3:88"。
-V 打印版本号并退出。
-k 使用HTTP的KeepAlive特性。
-d 不显示百分比。
-S 不显示预估和警告信息。
-g 输出结果信息到gnuplot格式的文件中。
-e 输出结果信息到CSV格式的文件中。
-r 指定接收到错误信息时不退出程序。
-h 显示用法信息,其实就是ab -help。

使用ab测试前注意事项

Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。

ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目标服务器造成巨大的负载,因此是某些DDOS攻击之必备良药,老少皆宜。自己使用也须谨慎。否则一次上太多的负载,造成目标服务器直接因内存耗光死机,而不得不硬重启,得不偿失。

在带宽不足的情况下,最好是本机进行测试,建议使用内网的另一台或者多台服务器通过内网进行测试,这样得出的数据,准确度会高很多。远程对web服务器进行压力测试,往往效果不理想(因为网络延时过大或带宽不足)

1. Mysql数据库并发调整

如果测试目标网站有连接数据库,先把mysql的最大连接数调高,否则在高并发时,mysql就会报错:Error 1040: Too many connections

调整方法1(命令行):连接上mysql: mysql -uroot -p

# 查可以看当前的最大连接数
show variables like 'max_connections';
# 设置最大连接数为1000,可以再次查看是否设置成功
set global max_connections=1000;
# 退出mysql命令行
exit

提示

这种方式有个问题,就是设置的最大连接数只在mysql当前服务进程有效,一旦mysql重启,又会恢复到初始状态。因为mysql启动后的初始化工作是从其配置文件中读取数据的,而这种方式没有对其配置文件做更改。

调整方法2(配置文件):

提示

本方法在ubuntu16.04下操作,其他发行版的Linux系统,请自行谷歌或百度一下。

这种方式说来很简单,只要修改MySQL配置文件my.cnf的参数max_connections,将其改max_connections=1000,然后重启MySQL即可。my.cnf 文件一般在 /etc/mysql 目录下

最大连接数比较理想的配置是:
Max_used_connections / max_connections * 100% ≈ 85%
最大连接数占上限连接数的85%左右,如果发现比例在10%以下,MySQL服务器连接上线就设置得过高了

2. ab错误:apr_socket_recv:Connection reset by peer (104)

解决方法一:使用参数 -r,如:

ab -r -n 10000 -c 1000 http://localhost:9090/hello

解决方法二:修改系统参数

apr_socket_recv这个是操作系统内核的一个参数,在高并发的情况下,内核会认为系统受到了SYN flood攻击,会发送cookies(possible SYN flooding on port 80. Sending cookies),这样会减慢影响请求的速度,所以在应用服务武器上设置下这个参数为0禁用系统保护就可以进行大并发测试了

# vim /etc/sysctl.conf
net.ipv4.tcp_syncookies = 0

# 保存退出后执行
sysctl -p

3. ab错误:apr_socket_recv:Connection timed out (110)

# vi /etc/sysctl.conf

# 在kernel2.6之前的添加项:
net.ipv4.netfilter.ip_conntrack_max =655360
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established= 180

# kernel2.6之后的添加项:
net.nf_conntrack_max = 655360
net.netfilter.nf_conntrack_tcp_timeout_established= 1200

# 保存退出后执行
sysctl -p /etc/sysctl.conf

注意

如果报错:error: “net.nf_conntrack_max” is an unknown key 则需要使用modprobe载入ip_conntrack模块,lsmod查看模块已载入。

4. ab错误:apr_poll: Thetimeout specified has expired (70007)

可以增加 -k 参数,保持连接进行测试。如:

ab -r -n 10000 -c 1000 -k http://localhost:9090/hello

5. ab的-c选项的参数最大到20000,如果想再大,只能修改源码再安装

6. -c选项的参数不能大于-n的参数

7. Failed requests(失败的请求)

在用ab测试的时候,只要出现Failed requests(失败的请求),就会出现三种失败的类型统计:Connect、Length、Exception。

...省略
Concurrency Level:      10000
Time taken for tests:   7.511 seconds
Complete requests:      15000
Failed requests:        55
   (Connect: 0, Receive: 0, Length: 55, Exceptions: 0)
Total transferred:      3294363 bytes
HTML transferred:       1449253 bytes
Requests per second:    1996.98 [#/sec] (mean)
Time per request:       5007.561 [ms] (mean)
Time per request:       0.501 [ms] (mean, across all concurrent requests)
Transfer rate:          428.31 [Kbytes/sec] received
...省略

说明:

Connect:向服务器发送请求失败;服务器连接失败;请求过程连接中断等。
Length:服务器返回的数据长度不一致,一般是对比Content-Length的值。
Exception:与服务器连接过程中发生意外错误。

这里主要说明一下Length,ab会把第一次成功返回的content-length作为基准,如果后面的请求返回的content-length跟第一次的不一样,它就会把这次请求当成是失败了。对于动态类型(如PHP)的网站,每次服务器返回的数据都不一定相同,所以如果ab提示的是Length错误,基本都可以忽略掉。

8. gzip压缩功能

默认情况下,ab没有启用gzip压缩功能,所以压力测试的结果会跟实际情况有很大的偏差。要想让ab使用gzip压缩功能,得添加参数-H 'Accept-Encoding: gzip',如:

ab -H 'Accept-Encoding: gzip' -n 10000 -c 1000 "www.xxx.com/"

测试结果说明

ab -r -n 15000 -c 10000 "http://127.0.0.1:8080/index.html"

This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
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 1500 requests
Completed 3000 requests
Completed 4500 requests
Completed 6000 requests
Completed 7500 requests
Completed 9000 requests
Completed 10500 requests
Completed 12000 requests
Completed 13500 requests
Completed 15000 requests
Finished 15000 requests


Server Software:        //服务器软件名称及版本信息
Server Hostname:        127.0.0.1 //服务器主机名
Server Port:            8080 //服务器端口

Document Path:          /index.html //请求的具体文件
Document Length:        81 bytes //请求的文件index.html大小

Concurrency Level:      10000 //并发级别,也就是并发数,请求中-c参数指定的数量
Time taken for tests:   7.511 seconds //本次测试总共花费的时间
Complete requests:      15000 //本次测试发起的总请求数
Failed requests:        55 //失败的请求数。因网络原因或服务器性能原因,发起的请求并不一定全部成功,通过该数值和Complete requests相除可以计算请求的失败率,作为测试结果的重要参考。
   (Connect: 0, Receive: 0, Length: 55, Exceptions: 0)
Total transferred:      3294363 bytes //总共传输的数据量,指的是ab从被测服务器接收到的总数据量,包括index.html的文本内容和请求头信息。
HTML transferred:       1449253 bytes //从服务器接收到的index.html文件的总大小
Requests per second:    1996.98 [#/sec] (mean) //平均每秒请求数,这个是非常重要的参数数值,服务器的吞吐量,QPS,这是一个平均值,等于Complete requests/Time taken for tests=15000/7.511
Time per request:       5007.561 [ms] (mean)  //从用户角度看,完成一个请求所需要的时间(因用户数量不止一个,服务器完成10个请求,平均每个用户才接收到一个完整的返回,所以该值是下一项数值的10倍。)
Time per request:       0.501 [ms] (mean, across all concurrent requests) //所有并发用户(这里是10000)都请求一次的平均时间
Transfer rate:          428.31 [Kbytes/sec] received //网络传输速度。对于大文件的请求测试,这个值很容易成为系统瓶颈所在。要确定该值是不是瓶颈,需要了解客户端和被测服务器之间的网络情况,包括网络带宽和网卡速度等信息。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0 1819 1236.2   2581    3220
Processing:     2 1086 782.1   1600    2094
Waiting:        1 1081 785.4   1599    2093
Total:          2 2905 1986.1   4448    5228
//这几行组成的表格主要是针对响应时间也就是第一个Time per request进行细分和统计。一个请求的响应时间可以分成网络链接(Connect),系统处理(Processing)和等待(Waiting)三个部分。表中min表示最小值; mean表示平均值;[+/-sd]表示标准差(Standard Deviation) ,也称均方差(mean square error),这个概念在中学的数学课上学过,表示数据的离散程度,数值越大表示数据越分散,系统响应时间越不稳定。 median表示中位数; max当然就是表示最大值了。

//需要注意的是表中的Total并不等于前三行数据相加,因为前三行的数据并不是在同一个请求中采集到的,可能某个请求的网络延迟最短,但是系统处理时间又是最长的呢。所以Total是从整个请求所需要的时间的角度来统计的。这里可以看到最慢的一个请求花费了195ms,这个数据可以在下面的表中得到验证。

Percentage of the requests served within a certain time (ms)
  50%   4448 //50%的请求在4.448s内返回 
  66%   4507 //66%的请求在4.507s内返回 
  75%   4596
  80%   4629
  90%   4675
  95%   4707
  98%   4730
  99%   4763
 100%   5228 (longest request)

测试样例

测试环境

4核8G Ubuntu16.04 64位 php7.0 Golang 1.8.3

基准测试(不连接mysql)

1. Nginx静态文件

测试参数配置:10000请求数,1000并发

ab压力测试-静态-nginx-n10000-c1000
ab压力测试-静态-nginx-n10000-c1000

没有失败请求数,QPS:12376.53

测试参数配置:190000请求数,19000并发

ab压力测试-静态-n190000-c19000
ab压力测试-静态-n190000-c19000

没有失败请求数,QPS:9755.61

2. 原生PHP

测试参数配置:10000请求数,1000并发

ab压力测试-原生PHP-n10000-c1000
ab压力测试-原生PHP-n10000-c1000

没有失败请求数,QPS:3127.91

测试参数配置:30000请求数,3000并发

ab压力测试-原生PHP-n30000-c3000
ab压力测试-原生PHP-n30000-c3000

没有失败请求数,QPS:1561.56

3.Go语言

测试参数配置:10000请求数,1000并发

ab压力测试-Go语言-n10000-c1000
ab压力测试-Go语言-n10000-c1000

没有失败请求数,QPS:15735.29

测试参数配置:200000请求数,20000并发

ab压力测试-GO语言-n200000-c20000
ab压力测试-GO语言-n200000-c20000

没有失败请求数,QPS:8331.95

如此大请求与并发数,依然没有失败请求数,go语言不愧为天生的高并发王者!

性能对比:

ab请求数和并发数语言QPS(每秒请求数)
10000请求数、1000并发数Nginx静态12376
190000请求数、19000并发数Nginx静态9755
10000请求数、1000并发数原生PHP3127
30000请求数、3000并发数原生PHP1561
10000请求数、1000并发数Go语言15735
200000请求数、20000并发数Go语言8331

基准测试(连接mysql)

连接mysql,查询一行数据

1. PHP

测试参数配置:10000请求数,1000并发

ab压力测试-php7.0-mysql-n10000-c1000
ab压力测试-php7.0-mysql-n10000-c1000

没有失败请求数,QPS:1328.38

测试参数配置:20000请求数,2000并发

ab压力测试-php7.0-mysql-n20000-c2000
ab压力测试-php7.0-mysql-n20000-c2000

没有失败请求数,QPS:733.59

测试参数配置:30000请求数,3000并发

ab压力测试-php7.0-mysql-n30000-c3000
ab压力测试-php7.0-mysql-n30000-c3000

没有失败请求数,QPS:568.32

2. Golang

测试参数配置:10000请求数,1000并发

ab压力测试-go-mysql-n10000-c1000
ab压力测试-go-mysql-n10000-c1000

没有失败请求数,QPS:9342.38

测试参数配置:180000请求数,18000并发

ab压力测试-go-mysql-n180000-c18000
ab压力测试-go-mysql-n180000-c18000

失败请求数:1303,QPS:7671.06

性能对比:

ab请求数和并发数语言QPS(每秒请求数)
10000请求数、1000并发数原生PHP1328
20000请求数、2000并发数原生PHP733
30000请求数、3000并发数原生PHP568
10000请求数、1000并发数Go语言9342
180000请求数、18000并发数Go语言7671
上次编辑于:
贡献者: Hyman
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.5