天天看點

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