网站性能压力测试是服务器网站性能调优过程当中必不可缺乏的一环。只有让服务器处在高压状况下,才能真正体现出软件、硬件等各类设置不当所暴露出的问题。php
性能测试工具目前最多见的有如下几种:ab、http_load、webbench、siege。今天咱们专门来介绍ab。html
ab是apache自带的压力测试工具。ab很是实用,它不只能够对apache服务器进行网站访问压力测试,也能够对或其它类型的服务器进行压力测试。好比nginx、tomcat、IIS等。linux
1、ab的原理nginx
ab是apachebench命令的缩写。web
ab的原理:ab命令会建立多个并发访问线程,模拟多个访问者同时对某一URL地址进行访问。它的测试目标是基于URL的,所以,它既能够用来测试apache的负载压力,也能够测试nginx、lighthttp、tomcat、IIS等其它Web服务器的压力。算法
ab命令对发出负载的计算机要求很低,它既不会占用很高CPU,也不会占用不少内存。但却会给目标服务器形成巨大的负载,其原理相似CC攻击。本身测试使用也须要注意,不然一次上太多的负载。可能形成目标服务器资源耗完,严重时甚至致使死机。shell
2、ab的安装apache
ab的安装很是简单,若是是源码安装apache的话,那就更简单了。apache安装完毕后ab命令存放在apache安装目录的bin目录下。以下:windows
/usr/local/apache2/bin数组
若是apache 是经过yum的RPM包方式安装的话,ab命令默认存放在/usr/bin目录下。以下:
which ab
注意:若是不想安装apache可是又想使用ab命令的话,咱们能够直接安装apache的工具包httpd-tools。以下:
yum -y install httpd-tools
查看ab是否安装成功,能够切换到上述目录下,使用ab –V命令进行检测。以下:
ab -V
若是ab安装成功,经过ab –V命令则会显示ab的相迎版本,如上图示。
注意以上是在linux平台下进行安装的,若是是windows平台下,咱们也能够下载对应的apache版本进行安装。
目前apache最新版2.4.10,apache官网已经没有windows下载的版本。可是咱们能够下载apache官网提供的集成软件包,以下:
3、ab参数说明
有关ab命令的使用,咱们能够经过帮助命令进行查看。以下:
ab --help
下面咱们对这些参数,进行相关说明。以下:
-n在测试会话中所执行的请求个数。默认时,仅执行一个请求。
-c一次产生的请求个数。默认是一次一个。
-t测试所进行的最大秒数。其内部隐含值是-n 50000,它可使对服务器的测试限制在一个固定的总时间之内。默认时,没有时间限制。
-p包含了须要POST的数据的文件。
-P对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。不管服务器是否须要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-T POST数据所使用的Content-type头信息。
-v设置显示信息的详细程度-4或更大值会显示头信息,3或更大值能够显示响应代码(404,200等),2或更大值能够显示警告和其余信息。
-V显示版本号并退出。
-w以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-i执行HEAD请求,而不是GET。
-x设置
属性的字符串。
-X对请求使用代理服务器。
-y设置
属性的字符串。
-z设置
属性的字符串。 -C对请求附加一个Cookie:行。其典型形式是name=value的一个参数对,此参数能够重复。 -H对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值的对(如,"Accept-Encoding:zip/zop;8bit")。 -A对服务器提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。不管服务器是否须要(即,是否发送了401认证需求代码),此字符串都会被发送。 -h显示使用方法。 -d不显示"percentage served within XX [ms] table"的消息(为之前的版本提供支持)。 -e产生一个以逗号分隔的(CSV)文件,其中包含了处理每一个相应百分比的请求所须要(从1%到100%)的相应百分比的(以微妙为单位)时间。因为这种格式已经“二进制化”,因此比'gnuplot'格式更有用。 -g把全部测试结果写入一个'gnuplot'或者TSV(以Tab分隔的)文件。此文件能够方便地导入到Gnuplot,IDL,Mathematica,Igor甚至Excel中。其中的第一行为标题。 -i执行HEAD请求,而不是GET。 -k启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能。 -q若是处理的请求数大于150,ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此-q标记能够抑制这些信息。
4、ab性能指标 在进行性能测试过程当中有几个指标比较重要: 一、吞吐率(Requests per second) 服务器并发处理能力的量化描述,单位是reqs/s,指的是在某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。 记住:吞吐率是基于并发用户数的。这句话表明了两个含义: a、吞吐率和并发用户数相关 b、不一样的并发用户数下,吞吐率通常是不一样的 计算公式:总请求数/处理完成这些请求数所花费的时间,即 Request per second=Complete requests/Time taken for tests 必需要说明的是,这个数值表示当前机器的总体性能,值越大越好。 二、并发链接数(The number of concurrent connections) 并发链接数指的是某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。 三、并发用户数(Concurrency Level) 要注意区分这个概念和并发链接数之间的区别,一个用户可能同时会产生多个会话,也即链接数。在HTTP/1.1下,IE7支持两个并发链接,IE8支持6个并发链接,FireFox3支持4个并发链接,因此相应的,咱们的并发用户数就得除以这个基数。 四、用户平均请求等待时间(Time per request) 计算公式:处理完成全部请求数所花费的时间/(总请求数/并发用户数),即: Time per request=Time taken for tests/(Complete requests/Concurrency Level) 五、服务器平均请求等待时间(Time per request:across all concurrent requests) 计算公式:处理完成全部请求数所花费的时间/总请求数,即: Time taken for/testsComplete requests 能够看到,它是吞吐率的倒数。 同时,它也等于用户平均请求等待时间/并发用户数,即 Time per request/Concurrency Level
5、ab实际使用 ab的命令参数比较多,咱们常用的是-c和-n参数。 虚拟主机a.ilanni.com建立完毕后,咱们如今就来测试apache的性能。使用以下命令: ab -c 10 -n 100 http://a.ilanni.com/index.php -c10表示并发用户数为10 -n100表示请求总数为100 http://a.ilanni.com/index.php表示请求的目标URL 这行表示同时处理100个请求并运行10次index.php文件。
经过测试,结果也一目了然,apache测试出的吞吐率为:Requests per second: 204.89[#/sec](mean)。 除此以外还有其余一些信息,须要说明下,以下: Server Software表示被测试的Web服务器软件名称。 Server Hostname表示请求的URL主机名。 Server Port表示被测试的Web服务器软件的监听端口。 Document Path表示请求的URL中的根绝对路径,经过该文件的后缀名,咱们通常能够了解该请求的类型。 Document Length表示HTTP响应数据的正文长度。 Concurrency Level表示并发用户数,这是咱们设置的参数之一。 Time taken for tests表示全部这些请求被处理完成所花费的总时间。 Complete requests表示总请求数量,这是咱们设置的参数之一。 Failed requests表示失败的请求数量,这里的失败是指请求在链接服务器、发送数据等环节发生异常,以及无响应后超时的状况。若是接收到的HTTP响应数据的头信息中含有2XX之外的状态码,则会在测试结果中显示另外一个名为“Non-2xx responses”的统计项,用于统计这部分请求数,这些请求并不算在失败的请求中。 Total transferred表示全部请求的响应数据长度总和,包括每一个HTTP响应数据的头信息和正文数据的长度。注意这里不包括HTTP请求数据的长度,仅仅为web服务器流向用户PC的应用层数据总长度。 HTML transferred表示全部请求的响应数据中正文数据的总和,也就是减去了Total transferred中HTTP响应数据中的头信息的长度。 Requests per second吞吐率,计算公式:Complete requests/Time taken for tests Time per request用户平均请求等待时间,计算公式:Time token for tests/(Complete requests/Concurrency Level)。 Time per requet(across all concurrent request)服务器平均请求等待时间,计算公式:Time taken for tests/Complete requests,正好是吞吐率的倒数。也能够这么统计:Time per request/Concurrency Level。 Transfer rate表示这些请求在单位时间内从服务器获取的数据长度,计算公式:Total trnasferred/ Time taken for tests,这个统计很好的说明服务器的处理能力达到极限时,其出口宽带的需求量。 Percentage of requests served within a certain time(ms)这部分数据用于描述每一个请求处理时间的分布状况,好比以上测试,80%的请求处理时间都不超过6ms,这个处理时间是指前面的Time per request,即对于单个用户而言,平均每一个请求的处理时间。
相关案例: 参数不少,通常咱们用 -c 和 -n 参数就能够了. 例如: ./ab -c 1000 -n 1000 http://127.0.0.1/index.php 这个表示同时处理1000个请求并运行1000次index.php文件. Benchmarking 127.0.0.1 (be patient)
Document Path: /index.html.zh-cn.gb2312 Concurrency Level: 1000 Connection Times (ms) Percentage of the requests served within a certain time (ms) 因为对于并发请求,cpu实际上并非同时处理的,而是按照每一个请求得到的时间片逐个轮转处理的,因此基本上第一个Time per request时间约等于第二个Time per request时间乘以并发请求数
使用shell把ab封装使用通常状况下,用ab进行压测时,只执行一次的话,结果不是很准,因此咱们就要手动的执行几回。这个操做很麻烦,这里写了个shell脚本,对apache的ab作了封装,只要传入指定的测试次数,自动进行,测试完成后返回平均的rps,以及最高和最低rps。 n: 每次ab请求的次数。 c: 并发请求数。 t: 执行ab的次数。 url: 压测的url,url必须是最后一个参数。 使用方法:sh rps.sh -n 20000 -c 1000 -t 10 localhost/lua_io 结果: avg rps: 12552 上代码: [plain] view plaincopyprint? 1. #!/bin/sh 2. 3. total_request=10000 4. concurrency=100 5. times=1 6. 7. cmd_idx=1 8. 9. param_count=$# 10. ## $# means param’s num, including param’s name and param’s content 11. ## such as ./rps.sh –n 1 –c 2 12. ## param_count is 4 , not 2 13. 14. while [ $cmd_idx -lt $param_count ] 15. do 16. 17. cmd=$1 18. ## $n means the nth parameter 19. 20. shift 1 #remove $1 21. ## shift 1 mean remove the first parameter,left forward 1,and param’ num - 1 22. ## shift 将$*中的剩余的参数向左移动一个位置并减小$#的值 23. 24. case $cmd in 25. -n) 26. total_request=$1 27. shift 1;; 28. -c) 29. concurrency=$1 30. shift 1;; 31. -t) 32. times=$1 33. shift 1;; 34. *) 35. echo "$cmd, support parameter: -n, -c, -t";; 36. esac 37. cmd_idx=`expr $cmd_idx + 2` 38. done 39. 40. url=$1 41. if [ $url = '' ]; then 42. echo 'the test url must be provided...' 43. exit 2 44. fi 45. 46. echo "Total Request: $total_request, Concurrency: $concurrency, URL: $url, Times: $times" 47. 48. ab_dir=/usr/bin 49. ab_cmd="$ab_dir/ab -n $total_request -c $concurrency $url" 50. 51. echo $ab_cmd 52. idx=1 53. rps_sum=0 54. max=-1 55. min=99999999 56. while [ $idx -le $times ] 57. do 58. echo "start loop $idx" 59. result=`$ab_cmd | grep 'Requests per second:'` 60. result=`echo $result | awk -F ' ' '{ print $4 }' | awk -F '.' '{ print $1 }'` 61. rps_sum=`expr $result + $rps_sum` 62. if [ $result -gt $max ]; then 63. max=$result 64. fi 65. if [ $result -lt $min ]; then 66. min=$result 67. fi 68. idx=`expr $idx + 1` 69. done 70. echo "avg rps: "`expr $rps_sum / $times` 71. echo "min rps: $min" 72. echo "max rps: $max"
备注: shell使用ab还不是很成功,可是能够经过这个例子明确封装的例子,还有shell对进行带进的参数也须要进行校验。
备注: $0 这个程式的执行名字 $n 这个程式的第n个参数值,n=1..9 $* 这个程式的全部参数,此选项参数可超过9个。 $# 这个程式的参数个数 $$ 这个程式的PID(脚本运行的当前进程ID号) $! 执行上一个背景指令的PID(后台运行的最后一个进程的进程ID号) $? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其余任何值代表有错误) $- 显示shell使用的当前选项,与set命令功能相同 $@ 跟$*相似,可是能够看成数组用 |