如何正确使用wrk
现在写完一个接口做测试的时候大家都喜欢用wrk来做一下接口性能压测。但是我发现往往不能正确使用wrk做接口压测。很多人一上来就喜欢直接干十几个线程、上百个连接来做测试。其实这样做是不对的。接下里我就给大家演示一下如何正确使用wrk做接口压力测试。
文章比较长,嫌麻烦的同学可以直接看总结部分。
验证
搭建如下测试环境
openresty demo
worker_processes 1; #压测时建议worker数设置为1,随着压力变大而调大。
events {
worker_connections 10240;
}
http {
server {
listen 1210;
access_log off;
# access_log logs/access_1210.log;
location = /cpu {
-- cpu计算密集
content_by_lua_block {
local sum = 0
-- 消耗cpu
for i = 1, 1000 * 100 * 2 do
sum = sum + 1
end
ngx.say(sum)
}
}
location = /sleep {
-- cpu闲置
content_by_lua_block {
ngx.sleep(0.5)
ngx.say("ok")
}
}
location = /ok {
echo "ok";
}
location = /t_echo_1KB {
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
}
location ~ {
# sendfile on;
root html;
}
}
}
wrk 脚本
for((i = 1; i < 10; i++)) do
./wrk -t 1 -c $i -d1m "http://172.26.186.7:1210/t_echo_1KB"
done
脚本执行过程就发现在线程数不增加的情况下随着线程数增加qps线性增长。
机器CPU/网络监控
目标机器CPU 随着每次连接数增加CPU和网络都有一次跳变
目标机器网络
wrk 机器CPU wrkCPU也随着每次连接数增加而增长
wrk 的运行逻辑
线程与连接的关系如下图所示。
wrk -t 5 -c 5
等价与 wrk -t 5 -c 9
。多余出来的4个连接由于无法均分给5个线程,所以9个连接并没有比5个连接qps高,而到了10个连接时则有了显著的翻倍。
wrk源码如下图所示,连接数除以线程数取整。
如何正确使用wrk做接口压测
首先使用单线程不断增加连接数,直到qps保持稳定。或者是p90、p99响应时间超过业务要求限制。在当期数值处画一条线,取得单线程最优连接数。 如图本次实验最优连接数是27-28(每个业务情况不同,27-28这个参数不可盲从)
单个连接线程数保持不变,不断增加线程数(建议到CPU核心数为止即可),直到整体出现qps水平。
如果qps没有出现随着线程数增长则是目标服务器性能已经达到瓶颈,wrk 单线程即可压测出目标机器最优qps。
如果qps一直没有出现水平趋势,则说明wrk压测机性能出现了瓶颈,需要扩大wrk压测机性能或者增加压测机器集群。
压测目标机器(左侧)和wrk在
wrk -t4 -c 108
压测环境下的实时CPU监控负载。可以看到目标机器CPU基本都吃满了,而且很多都处于内核态是由于此时系统在处理大量的网络IO。
总结
wrk原理
wrk 是基于IO复用模型做的压测。
wrk 没必要使用过多的线程,最开始可以使用单线程线程做测试。
wrk 的线程数一定要可以整除连接数,否则多余的连接没有意义。
只有发现wrk 单线程cpu使用率超过90%之后才有必要添加线程。
wrk 中的连接数相当于是向服务端发起了多个连接通道。也就是大家常说的并发。
wrk 默认测试均是长连接,做测试,如果想要做短连接测试的话可以在服务端配置
keepalive_timeout 0; add_header Connection "close";
一些小经验
wrk 压测是发现 wrk、目标机器CPU均没有出现瓶颈,这种情况需要关注 wrk 与目标机器的网络是否已经吃满。主要查看带宽、pps指标。
wrk 在压力变大之后产生的
Latency Distribution
有一定的不准确性(对比用服务端记录的访问时间计算的p99偏大)。可以看看温铭写的文章。wrk 支持luajit,可以做很多很好玩的事情,比如除了wrk自己提供的数据统计分析之外还可以自己做更多的统计分析。比如业务定制之类的。
后面我会继续分享一些如何使用wrk的高级技巧。大家有什么想探讨的也可以一起交流