之前知道一般网站性能可以通过 LoadRunner, JMeter, QTP 等相应的软件进行测试, 印象中本科学习 “软件测试” 这门课程时安装并使用过, LoadRunner等不是一个小软件, 安装不是那么的容易.
最近发现Apache还有一款小巧玲珑的工具可以直接用来做压力测试, 相关文档可以参见 Apache ab 官网.
Mac 下自带(具体记不清是因为我安装了Apache还是系统自带的了)了这个 ab
工具(Apache HTTP server benchmarking tool), ab 我猜应该就是 Apache Benchmarking
的缩写吧?
ab 用法
ab 命令参数如下,
ab [ -A auth-username:password ] [ -b windowsize ] [ -B local-address ] [ -c concurrency ] [ -C cookie-name=value |
不过常用的, 也就是, -n
跟请求数, -c
跟并发数.
-n requests Number of requests to perform |
在对网站进行测试的时候, 可能需要登录态进行测试, 可以通过 -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
一致.
然后进行完整的测试, 可以得到详细的结果报告.
# 200并发,一共10000请求 |
ab post “bug”
在某个场景下, 我需要对其中一个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默认会在文件末尾添加一个文件结束符(换行符 0A
), vim 默认配置 'endofline' 'eol' boolean (default on)
, 可以通过 set noendofline
解决. (vim相关帮助文档如下)
‘endofline’ ‘eol’ boolean (default on)
When writing a file and this option is off and the ‘binary’ option
is on, or ‘fixeol’ option is off, nowill be written for the
last line in the file. This option is automatically set or reset when
starting to edit a new file, depending on whether file has an
for the last line in the file. Normally you don’t have to set or
reset this option.
When ‘binary’ is off and ‘fixeol’ is on the value is not used when
writing the file. When ‘binary’ is on or ‘fixeol’ is off it is used
to remember the presence of afor the last line in the file, so
that when you write the file the situation from the original file can
be kept. But you can change it if you want to.
实际过程中,(去掉文件末尾的换行符可以解决), 或者将postdata多添加一个参数可以解决(这个参数server端没有用到时多余的, form可以正常解析, 因此 response 正常了).
下面来重现一下这个过程, 拿百度为例吧.
➜ com~apple~CloudDocs$ cat postdata.txt |
用 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/'
抓包得到以下结果
➜ ~ sudo tcpdump -X host www.baidu.com |
用 curl 执行并抓包的结果是:
... |
发现HTTP协议版本号不同, UA不同, Content-Length不同.
刚开始还以为是ab的bug, 最后发现确实是 Content-Length
相差1, 而多的这个字符换行符导致了 server 段的 form 填充失败(上例中体现不了, 反正post百度无效的请求).
➜ com~apple~CloudDocs$ wc -c postdata.txt |
最后去掉postdata文件末尾的结束符后, 得以成功.