(题图: 某偏远山沟小河 effected by google photos)
以前知道通常网站性能能够经过 LoadRunner, JMeter, QTP 等相应的软件进行测试, 印象中本科学习 “软件测试” 这门课程时安装并使用过, LoadRunner等不是一个小软件, 安装不是那么的容易.
最近发现Apache还有一款小巧玲珑的工具能够直接用来作压力测试, 相关文档能够参见 Apache ab 官网.
Mac 下自带(具体记不清是由于我安装了Apache仍是系统自带的了)了这个 ab 工具(Apache HTTP server benchmarking tool), ab 我猜应该就是 Apache Benchmarking 的缩写吧?
ab 用法
ab 命令参数以下,apache
ab [ -A auth-username:password ] [ -b windowsize ] [ -B local-address ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-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]://]host- name[:port]/path
不过经常使用的, 也就是, -n 跟请求数, -c 跟并发数.vim
-n requests Number of requests to perform -c concurrency Number of multiple requests to make at a time
在对网站进行测试的时候, 可能须要登陆态进行测试, 能够经过 -C 加 Cookie的方式进行测试, 测试以前, 最好确认这个命令用法是否正确, 只用1个请求看看响应的长度是否一致(能够经过 与 curl 命令的结果进行对比).
例如, 经过 ab -c 1 -n 1 -C 'cookiedata=xxx' "http://shangtongdai.yxapp.xyz/loans" 获得的 Document Length: 53218 bytes 和用 curl -b 'cookiedata=xxx' "http://shangtongdai.yxapp.xyz/loans" 获得的Content-Length: 53218 一致.
而后进行完整的测试, 能够获得详细的结果报告.windows
# 200并发,一共10000请求 ab -c 200 -n 10000 -C 'cookiedata=xxx' "http://shangtongdai.yxapp.xyz/loans" # 结果 This is ApacheBench, Version 2.3 <$Revision: 1663405 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking shangtongdai.yxapp.xyz (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Tengine/2.1.1 Server Hostname: shangtongdai.yxapp.xyz Server Port: 80 Document Path: /loans Document Length: 53218 bytes Concurrency Level: 200 Time taken for tests: 53.098 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 534570000 bytes HTML transferred: 532180000 bytes Requests per second: 188.33 [#/sec] (mean) Time per request: 1061.967 [ms] (mean) Time per request: 5.310 [ms] (mean, across all concurrent requests) Transfer rate: 9831.59 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 1.8 1 39 Processing: 38 1055 344.1 1046 2964 Waiting: 37 1051 345.5 1043 2959 Total: 39 1056 344.4 1047 2969 Percentage of the requests served within a certain time (ms) 50% 1047 66% 1170 75% 1252 80% 1311 90% 1477 95% 1657 98% 1860 99% 1986 100% 2969 (longest request)
在某个场景下, 我须要对其中一个post的接口进行测试.
根据 ab 的 mannual 看到 post 时候, 须要将post的data用文件保存, 而后经过参数 -p postdata.file 传输.
但在实际ab进行测试时, 发现返回的结果异常, 正常状况下 response 的size比经过ab返回的response size大得多, 说明经过ab发送的http请求失败了.
通过tcpdump抓包最后发现 ab 请求无效的缘由是: postdata 文件会多一个字符(文件末尾的换行符), 致使server端的 form 解析失败, 于是返回异常的response.
这个坑是vim的默认配置致使的, vim默认会在文件末尾添加一个文件结束符, vim 默认配置 'endofline' 'eol' boolean (default on) , 能够经过 set noendofline解决.
实际过程当中,(去掉文件末尾的换行符能够解决), 或者将postdata多添加一个参数能够解决(这个参数server端没有用到时多余的, form能够正常解析, 所以 response 正常了).
下面来重现一下这个过程, 拿百度为例吧.cookie
➜ com~apple~CloudDocs$ cat postdata.txt a=65&b=66
用 curl 执行, curl -i -H "Content-Type: application/x-www-form-urlencoded" -d "a=65&b=66" "http://www.baidu.com".
用 ab 执行, ab -c 1 -n 1 -T 'application/x-www-form-urlencoded;' -p postdata.txt 'http://www.baidu.com/'
抓包获得如下结果
用 curl 执行并抓包的结果是:
发现HTTP协议版本号不一样, UA不一样, Content-Length不一样.
刚开始还觉得是ab的bug, 最后发现确实是 Content-Length 相差1, 而多的这个字符换行符致使了 server 段的 form 填充失败(上例中体现不了, 反正post百度无效的请求).并发
➜ com~apple~CloudDocs$ wc -c postdata.txt 10 postdata.txt ➜ com~apple~CloudDocs$ ll postdata.txt -rw-r--r--@ 1 tanglei staff 10B 4 11 21:26 postdata.txt ➜ com~apple~CloudDocs$ cat postdata1.txt a=65&b=66% ➜ com~apple~CloudDocs$ wc -c postdata1.txt 9 postdata1.txt ➜ com~apple~CloudDocs$ ll postdata1.txt -rw-r--r--@ 1 tanglei staff 9B 4 11 21:26 postdata1.txt
最后去掉postdata文件末尾的结束符后, 得以成功.app