介绍
wrk 是一款简单的 HTTP 压测工具。最大的优点就是能使用很少的线程压出很大的并发量,原因是它使用了一些操作系统特定的高性能 IO 机制,比如 select,epoll 等,其实它是复用了 Redis 的 ae 异步事件。
GitHub 地址:https://github.com/wg/wrk
安装
代码语言:javascript复制git clone https://github.com/wg/wrk.git
cd wrk
make
编译出的可执行程序 wrk
就在 Makefile 文件所在目录。链接或者添加一下环境变量,就能随时使用这个工具了。
简单使用
代码语言:javascript复制michaelliu@C02ZRD0ZMD6N ~ % wrk -t4 -c2500 -d20 "https://www.baidu.com"
Running 20s test @ https://www.baidu.com
4 threads and 2500 connections
Thread Stats Avg Stdev Max /- Stdev
Latency 518.51ms 387.16ms 2.00s 71.39%
Req/Sec 85.09 33.16 202.00 63.53%
6708 requests in 20.07s, 101.78MB read
Socket errors: connect 2254, read 0, write 0, timeout 357
Requests/sec: 334.31
Transfer/sec: 5.07MB
其中,
-t
代表需要模拟的线程数
-c
代表需要模拟的连接数
-d
代表测试的持续时间
-timeout
超时时间
-latency
显示延迟时间
搭配 Lua 脚本使用
在基本压测中,每次发送的请求都是一样的,很多时候我们压测的请求体是每个请求都不一样,这时候就要写 lua 脚本来压测。
login.lua:
代码语言:javascript复制#!/usr/local/bin/lua
wrk.path = "/api/login"
-- user_name password list:
account_list = {
'{"user_name": "YIkQ3SIs0", "password": "Sttv5ZNYLx"}',
'{"user_name": "wARAaC6vzeUM0f", "password": "OLefD"}',
'{"user_name": "TDIJy5MghU1w", "password": "XESjfruKP"}',
}
local counter = 1
local threads = {}
function setup(thread)
thread:set("id", counter)
table.insert(threads, thread)
counter = counter 1
end
function init(args)
requests = 0
responses = 0
local msg = "thread %d created"
print(msg:format(id))
end
function request()
local headers = { }
headers['Content-Type'] = "application/json"
wrk.body = account_list[math.random(1, 200)]
requests = requests 1
return wrk.format('POST', path, headers)
end
function response(status, headers, body)
if status ~= 200 then
print(status)
end
responses = responses 1
end
-- 获取cookie
function getCookie(cookies, name)
local start = string.find(cookies, name .. "=")
if start == nil then
return nil
end
return string.sub(cookies, start #name 1, string.find(cookies, ";", start) - 1)
end
-- 统计信息
function done(summary, latency, requests)
for index, thread in ipairs(threads) do
local id = thread:get("id")
local requests = thread:get("requests")
local responses = thread:get("responses")
local msg = "thread %d made %d requests and got %d responses"
print(msg:format(id, requests, responses))
end
end
使用 -s
参数,添加 lua 脚本即可:
michaelliu@C02ZRD0ZMD6N lua % wrk -t 16 -c 200 -d 20s --latency -s login.lua http://localhost:8080
Running 20s test @ http://localhost:8080
16 threads and 200 connections
Thread Stats Avg Stdev Max /- Stdev
Latency 23.19ms 43.21ms 496.29ms 96.93%
Req/Sec 711.56 146.29 0.90k 90.01%
Latency Distribution
50% 15.98ms
75% 19.22ms
90% 23.26ms
99% 290.49ms
220146 requests in 20.06s, 93.24MB read
Requests/sec: 10976.13
Transfer/sec: 4.65MB
所以上面参数的意思就是 16 个线程,200 个连接,持续 20s,使用脚本 login.lua
,可以看到 Requests/sec
就是 QPS
是 10976.13。