天天看点

wrk 现代HTTP压测工具,动态构建请求

HTTP压测工具通用的比如apache ab, httpload, 但碰到有些请求是动态构建的,比如需要时间校验,需要做md5加密,这些工具就比较尴尬了。还好有wrk(https://github.com/wg/wrk)你可以使用,可以内嵌lua脚本,通过luajit加速,当然如果需要做分布式压测,可以试试locust(https://github.com/locustio/locust),使用了Python的Gevent,rpc使用了zeromq,代码还是很简洁的,感兴趣可以看看,不过发现问题不少,而且开发者不积极。

最近给上报接口做简单压测,涉及到请求动态构建和md5签名,试用了下wrk,效果还是蛮不错的,wrk提供的lua hook可以参考http://type.so/linux/lua-script-in-wrk.html。

package.path = '/root/wrk/?.lua;'

local md5 = require "md5"
local body   = [[BI_login|userid{145030}|openid{4-22761563}|source{}|affiliate{}|creative{}|family{}|genus{0}|ip{180.111.151.116}|from_uid{0}|login_date{2016-11-04}|login_time{10:40:13}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}
BI_logout|userid{184103}|openid{4-22784181}|family{}|genus{0}|ip{218.2.96.82}|logout_date{2016-11-04}|logout_time{10:40:42}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}
BI_role_logout|roleid{184103}|userid{184103}|openid{4-22784181}|ip{218.2.96.82}|level{100}|money{468}|power{1}|exp{252}|lijin{0}|online_time{0}|mapid{0}|posx{0}|posy{0}|rolelogout_date{2016-11-04}|rolelogout_time{10:40:42}|extra{0}|srcid{0}|snid{1002}|clientid{1253}|gameid{2100012}
BI_logout|userid{71084}|openid{4-20974629}|family{}|genus{0}|ip{117.136.8.76}|logout_date{2016-11-04}|logout_time{10:40:43}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}]] 

--local body = "hello"
wrk.headers["Content-Type"] = "text/xml"

local i=
request = function()
    i = i+
    local path = "/v1/pub?gameid=510038&timestamp=%s&key=510038&type=basic&sign=%s"
    local time = os.time()*
    local v = "510038" .. time .. "basic98889999"
    local sign = md5.sumhexa(v)
    path = string.format(path, time, sign)
    --print(path)
    return wrk.format("POST", path, nil, body)
end
           

md5模块使用了https://github.com/kikito/md5.lua

wrk 现代HTTP压测工具,动态构建请求

-t代表使用的线程数,-c是连接数,-T是超时时间,wrk默认运行10s

测试机器和42都是24核的机器,42运行的openresty work也是24。

测试的接口是把post的数据异步放进kafka中,看着性能还是很好的,但明显看到随着连接数的增加,出现部分socket error。

测试时需要增加打开的文件数量,ulimit -n 204800

在测试openresty时,发现某一时刻worker一直在重启,查看errlog发现是收到SIGXFSZ信号,当某个进程写日志,单个文件超过限制,操作系统就会发送SIGXFSZ信号。可通过ulimit -f查看

n []: *///
Out[]: 
           

也就是单个文件超过1.9G,操作系统就会发送SIGXFSZ信号。可调大该值或定期切换nginx日志,可通过logrotate切换,或手动写脚本切换。

$ mv access.log access.log.
$ kill -USR1 `cat master.nginx.pid`
$ sleep 
$ gzip access.log.    # do something with access.log.0
           

线上机器最好调整ulimit,现在用云服务器基本都已经设置好了

[root@localhost ~]# ulimit -a
core file size          (blocks, -c) 
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 
file size               (blocks, -f) unlimited
pending signals                 (-i) 
max locked memory       (kbytes, -l) 
max memory size         (kbytes, -m) unlimited
open files                      (-n) 
pipe size            ( bytes, -p) 
POSIX message queues     (bytes, -q) 
real-time priority              (-r) 
stack size              (kbytes, -s) 
cpu time               (seconds, -t) unlimited
max user processes              (-u) 
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
           

测试时还发现一个问题,发现kafka接受者动不动就卡死了,用strace发现卡在

# strace -T -tt -e trace=all -p 18432
write(, "\n", )
           

为啥总卡在write这呢?写文件不至于啊?哎,就没认真看write的第一个参数是1,这是标准输出的fd,由于我是远程连接测试机器的,标准输出会重定向到ssh,我估计是输出终端的日志太多导致的,这也就解释了当kill -9时终端输出write failed: broken pipe了。这个问题卡了半天,最后才发现write的fd是1,还是缺少火眼金睛啊。