tags: wrk, benchmark, lua
wrk
is a high performance http benchmark tool written with C. It uses the same
even module as redis. A simple example test is like following:
$ wrk -c 10 -d 3s --latency 'http://127.0.0.1/' -H 'host:test.local'
Running 3s test @ http://127.0.0.1/
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 90.83ms 51.74ms 329.00ms 87.11%
Req/Sec 62.83 22.23 100.00 73.08%
Latency Distribution
50% 67.86ms
75% 95.00ms
90% 165.07ms
99% 278.71ms
350 requests in 3.05s, 1.19MB read
Requests/sec: 114.78
Transfer/sec: 398.05KB
It shows qps and latency Distribution. However it doesn't separate different http status codes. Abnormal response like 502, 502, 401 are mixed with 200.
Yes, it seems that wrk
is weak.
- not support non GET request like POST, PUT
- cannot distinct 200 response and others
- cannot limit total request amount
However, wrk
supports LuaJIT
script that you can write powerful script to do
complex test. There are many official examples at
here.
Write a post.lua script
wrk.method = 'POST'
wrk.path = '/api/test'
wrk.body = '{"id": 10}'
wrk.headers["Content-Type"] = 'application/json'
Then call it using the -s, --script
option.
wrk -c 60 -d 2s --latency 'http://127.0.0.1:3000/' -s post.lua
Write a status.lua script
wrk.method = 'POST'
threads = {}
function setup(thread)
table.insert(threads, thread)
end
status_counter = {}
function response(status, headers, body)
if status_counter[status] == nil then
status_counter[status] = 1
else
status_counter[status] = status_counter[status] + 1
end
end
function done()
for index, thread in ipairs(threads) do
local status = thread:get("status_counter")
print("http status counter")
for k,v in pairs(status) do
print('code ', k, ' : ',v)
end
end
end
You can setup multiple threads to run the benchmark. By default, wrk
will 2
threads. The setup
and response
functions worked at each thread. However
function done
is run after the thread joined. Then we cannot access local
variables directly. We need to use shared global variables.
At above example, we use the dict status_counter
to store request counter of
each http status code and print it finally.
We can use lua to do much much more. Like print or sample the response to debug. Add random delay to request. Construct different url or body for each request.
Enjoy powerful wrk.