简单的 http 性能测试工具
一个简单的 http benchmark 工具, 能做很多基本的 http 性能测试.
wrk 的一个很好的特性就是能用很少的线程压出很大的并发量.
原因是它使用了一些操作系统特定的高性能 io 机制, 比如 select, epoll, kqueue 等.
其实它是复用了 redis 的 ae 异步事件驱动框架. 确切的说 ae 事件驱动框架并不是 redis 发明的, 它来至于 Tcl的解释器 jim, 这个小巧高效的框架, 因为被 redis 采用而更多的被大家所熟知。
要用 wrk, 首先要编译 wrk
你的机器上需要已经安装了 git 和基本的c编译环境。wrk 本身是用 c 写的并且没有使用很多第三方库. 所以编译基本不会遇到什么问题(运行不会存在太大难度)。
安装
Mac 安装
brew install wrk
注意: mac 本身连接数有限制,不要做太大的测试
Linux 安装
git clone https://github.com/wg/wrk.git
cd wrk
make
成功以后在目录下有一个 wrk
文件,将这个文件复制到你的软件目录,配置好环境变量即可,这里就不细说了
编译错误
fatalerror: openssl/ssl.h: Nosuchfileor directory
是因为系统中没有安装openssl的库
sudo apt-get install libssl-dev
# or run
sudo yum install openssl-devel
使用
简单的性能测试
wrk -t12 -c100 -d30s http://192.168.31.107
# 输出为
12 threadsand 100 connections
ThreadStats Avg Stdev Max +/- Stde
Latency 538.64ms 368.66ms 1.99s 77.33
Req/Sec 15.62 10.28 80.00 75.35
5073 requestsin 30.09s, 75.28MB rea
Socketerrors: connect 0, read 5, write 0, timeout 6
Requests/sec: 168.5
Transfer/sec: 2.50M
- -t12 为模拟12个用户线程 -c100模拟100个连接
一般线程数不宜过多. 核数的2到4倍足够,wrk 不是使用每个连接一个线程的模型, 而是通过异步网络 io 提升并发量. 所以网络通信不会阻塞线程执行
结果统计分析
线程统计分析
项目 | 名称 | 说明 |
---|---|---|
Avg | 平均值 | 每次测试的平均值 |
Stdev | 标准偏差 | 结果的离散程度,越高说明越不稳定 |
Max | 最大值 | 最大的一次结果 |
+/- Stdev | 正负一个标准差占比 | 结果的离散程度,越大越不稳定 |
Latency: 可以理解为响应时间
Req/Sec: 每个线程每秒钟的完成的请求数
一般我们来说我们主要关注平均值和最大值.
标准差如果太大说明样本本身离散程度比较高. 有可能系统性能波动很大
读写分析
- 总共完成请求数
- 读取数据量
- 错误统计
5073 requestsin 30.09s, 75.28MB rea
Socketerrors: connect 0, read 5, write 0, timeout 6
Requests/sec: 168.5
Transfer/sec: 2.50M
wrk Post 接口测试
首先需要准备一个lua文件
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
wrk.body = "youbody&youset"
这个文件内容建议自己填写,保存为 post.lua
文件
当然这个脚本内容可以再次定义,具体查看wrk的git文档
执行脚本
wrk -t4 -c2000 -d60s -T5s --script=post.lua --latency http://192.168.31.107/user/login
这样就是模拟4个线程,2000个连接,在60s内,间隔5s 执行 post.lua 的请求
- 你可以扩展一下,制作 shell 脚本来批量测试各种接口
如测试post json:
post.lua
-- example HTTP POST script which demonstrates setting the
-- HTTP method, body, and adding a header
wrk.method = "POST"
wrk.body = "{"q":1}"
wrk.headers["Content-Type"] = "application/json"