ab命令原理
Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。
ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目标服务器造成巨大的负载,因此是某些DDOS攻击之必备良药,老少皆宜。自己使用也须谨慎。否则一次上太多的负载,造成目标服务器直接因内存耗光死机,而不得不硬重启,得不偿失。
在带宽不足的情况下,最好是本机进行测试,建议使用内网的另一台或者多台服务器通过内网进行测试,这样得出的数据,准确度会高很多。远程对web服务器进行压力测试,往往效果不理想(因为网络延时过大或带宽不足)
ab 命令格式:
ab [ -A auth-username:password ] [ -b windowsize ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -f protocol ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username:password ] [ -q ] [ -r ] [ -s ] [ -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
经常用到的参数是:
-c 并发数
-n 请求数
-k 保持连接
比如 :
ab -c1000 -n10000 http://test.dev/
返回的结果:
[root@piaoyi.ORG ~]# /usr/local/apache/bin/ab -c15000 -n150000 http://test.dev/ This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking test.dev (be patient) Completed 15000 requests Completed 30000 requests Completed 45000 requests Completed 60000 requests Completed 75000 requests Completed 90000 requests Completed 105000 requests Completed 120000 requests Completed 135000 requests Completed 150000 requests Finished 150000 requests Server Software: nginx Server Hostname: test.dev Server Port: 80 Document Path: / Document Length: 123 bytes #HTTP响应数据的正文长度 Concurrency Level: 15000 Time taken for tests: 48.416 seconds #所有这些请求处理完成所花费的时间 Complete requests: 150000 #完成请求数 Failed requests: 0 #失败请求数 Write errors: 0 Total transferred: 40950000 bytes HTML transferred: 18450000 bytes Requests per second: 3098.17 [#/sec] (mean) #QPS-每秒请求数 Time per request: 4841.572 [ms] (mean) Time per request: 0.323 [ms] (mean, across all concurrent requests) Transfer rate: 825.98 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1792 1722.4 1394 32126 Processing: 1 2796 1533.7 2515 10268 Waiting: 1 2499 1484.1 2200 9987 Total: 3 4588 2199.0 4632 34177 Percentage of the requests served within a certain time (ms) 50% 4632 66% 5381 75% 5975 80% 6317 90% 6778 95% 7562 98% 9299 99% 9355 100% 34177 (longest request)
最后这一项
Percentage of the requests served within a certain time (ms)
代表50%的请求在4.6秒内完成了,99%的请求在9.3秒内完成,所有请求完成需要34秒。说明最后的1%的请求消耗了大量的时间,对于正常的用户响应来说,这是不行的,所有的并发请求应该控制在5秒内完成,再长的时间等待对于用户来说是不可接受的。
通过把这行数据(longest request)控制在5秒内,我们可以得出一台服务器适当的并发能力到底是多少。
高并发测试的注意点:
1、Mysql数据库并发调整
如果需要连接mysql数据库,先把mysql的并发连接数提高,my.cnf里面:
[mysqld]
thread_cache_size = 256
max_connections = 10000
否则在高并发时,mysql就会报错:
Error 1040: Too many connections
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
然后就可以超过1000个并发测试了。
解决方法三:
重新编译ab,修改ab.c文件,大约1380行处:
}else {
//apr_err("apr_socket_recv", status); // 从这开始
bad++;
close_connection(c);
return; // 到这里
}
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
[long@longhao etc]# sysctl -p/etc/sysctl.conf
如果报错:error: “net.nf_conntrack_max” is an unknown key 则需要使用modprobe载入ip_conntrack模块,lsmod查看模块已载入。
[long@longhao etc]# modprobe ip_conntrack
4、ab错误:apr_poll: Thetimeout specified has expired (70007)
由于某些框架太大(比如laravel框架),超时了,可以增加 -k 参数,保持连接进行测试。
5、 ab的-c选项的参数最大到20000,如果想再大,只能修改源码再安装
6、-c选项的参数不能大于-n的参数
7、Failed requests(失败的请求)
在用ab测试的时候,只要出现Failed requests(失败的请求),就会出现三种失败的类型统计:Connect、Length、Exception。
Concurrency Level: 1000 Time taken for tests: 2.629 seconds Complete requests: 100000 Failed requests: 10018 (Connect: 0, Receive: 0, Length: 10018, Exceptions: 0) Write errors: 0 Non-2xx responses: 7
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' www.xxx.com/
9、带参数的压力测试示例
ab 'www.xxx.com/?a=1&b=2&c=3'
完。