function response(status, headers, body)
if status ~= 200 then
print(body)
wrk.thread:stop()
end
end
done函数在所有请求执行完以后调用, 一般用于自定义统计结果.
done = function(summary, latency, requests)
io.write("------------------------------\n")
for _, p in pairs({ 50, 90, 99, 99.999 }) do
n = latency:percentile(p)
io.write(string.format("%g%%,%d\n", p, n))
end
end
下面是 wrk 源代码中给出的完整例子:
localcounter = 1
localthreads = {}
function setup(thread)
thread:set("id", counter)
table.insert(threads, thread)
counter = counter + 1
end
function init(args)
requests = 0
responses = 0
localmsg = "thread %d created"
print(msg:format(id))
end
function request()
requests = requests + 1
return wrk.request()
end
function response(status, headers, body)
responses = responses + 1
end
function done(summary, latency, requests)
for index, threadin ipairs(threads) do
localid = thread:get("id")
localrequests = thread:get("requests")
localresponses = thread:get("responses")
localmsg = "thread %d made %d requests and got %d responses"
print(msg:format(id, requests, responses))
end
end
测试复合场景时, 也可以通过 lua 实现访问多个 url.例如这个复杂的 lua 脚本, 随机读取 paths.txt 文件中的 url 列表, 然后访问.:
counter = 1
math.randomseed(os.time())
math.random(); math.random(); math.random()
function file_exists(file)
local f = io.open(file, "rb")
if f then f:close() end
return f ~= nil
end
function shuffle(paths)
local j, k
local n = #paths
for i = 1, n do
j, k = math.random(n), math.random(n)
paths[j], paths[k] = paths[k], paths[j]
end
return paths
end
function non_empty_lines_from(file)
if not file_exists(file) then return {} end
lines = {}
for linein io.lines(file) do
if not (line == '') then
lines[#lines + 1] = line
end
end
return shuffle(lines)
end
paths = non_empty_lines_from("paths.txt")
if #paths <= 0 then
print("multiplepaths: No paths found. You have to create a file paths.txt with one path per line")
os.exit()
end
print("multiplepaths: Found " .. #paths .. " paths")
request = function()
path = paths[counter]
counter = counter + 1
if counter > #paths then
counter = 1
end
return wrk.format(nil, path)
end
关于 cookie
有些时候我们需要模拟一些通过 cookie 传递数据的场景. wrk 并没有特殊支持, 可以通过 wrk.headers[“Cookie”]=”xxxxx”实现.
下面是在网上找的一个离职, 取 Response的cookie作为后续请求的cookie
function getCookie(cookies, name)
localstart = string.find(cookies, name .. "=")
if start == nilthen
return nil
end
return string.sub(cookies, start + #name + 1, string.find(cookies, ";", start) - 1)
end
response = function(status, headers, body)
localtoken = getCookie(headers["Set-Cookie"], "token")
if token ~= nilthen
wrk.headers["Cookie"] = "token=" .. token
end
end
wrk 本身的定位不是用来替换 loadrunner 这样的专业性能测试工具的. 其实有这些功能已经完全能应付平时开发过程中的一些性能验证了.
原文转自: https://blog.satikey.com/p/5768/wrk-the-compact-and-lightweight-htt