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×tamp=%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

-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,还是缺少火眼金睛啊。