wrk 压测工具
文章目录
基于事件机制的高性能 HTTP 压力测试工具。
wrk 负载测试时可以运行在一个或者多核CPU,wrk 结合了可伸缩的事件通知系统 epoll 和 kqueue 等多线程设计思想。wrk 不仅能测试单条 URL,还能通过
LuaJIT
脚本实现对不同的 URL 和参数、请求内容进行测试。
参数
|
|
安装
-
macOS brew
1
brew install wrk
-
CentOS
1 2 3 4 5 6 7
sudo yum groupinstall 'Development Tools' sudo yum install -y openssl-devel git git clone https://github.com/wg/wrk.git wrk cd wrk make # move the executable to somewhere in your PATH sudo cp wrk /somewhere/in/your/PATH
-
Ubuntu
1 2 3 4 5 6
sudo apt-get install build-essential libssl-dev git -y git clone https://github.com/wg/wrk.git wrk cd wrk sudo make # move the executable to somewhere in your PATH, ex: sudo cp wrk /usr/local/bin
普通示例
|
|
使用Lua脚本个性化wrk压测
wrk支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua运行环境。
请求方式,命令中添加参数-s <lua path>
:
wrk -t1 -c100 -d10s -s post_test.lua --latency http://test.com
启动阶段
function setup(thread)
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
|
|
运行阶段
function init(args)
init由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
function delay()
delay在每次发送request之前调用,如果需要delay,那么delay相应时间;
function request()
request用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
function response(status, headers, body)
reponse在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
结束阶段
function done(summary, latency, requests)
该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
自定义脚本中可访问的变量和方法
变量:wrk
|
|
一个table类型的变量wrk,是全局变量,修改该table,会影响所有请求。
方法:wrk.fomat
、wrk.lookup
、wrk.connect
-
function wrk.format(method, path, headers, body)
wrk.format returns a HTTP request string containing the passed parameters merged with values from the wrk table. 根据参数和全局变量wrk,生成一个HTTP rquest string。
-
function wrk.lookup(host, service)
wrk.lookup returns a table containing all known addresses for the host and service pair. This corresponds to the POSIX getaddrinfo() function. 给定host和service(port/well known service name),返回所有可用的服务器地址信息。
-
function wrk.connect(addr)
wrk.connect returns true if the address can be connected to, otherwise it returns false. The address must be one returned from wrk.lookup(). 测试与给定的服务器地址信息是否可以成功创建连接
脚本示例
-
POST请求脚本
通过修改全局变量wrk,使得所有请求都使用POST方法,并指定了body和Content-Type头。
1 2 3
wrk.method = "POST" wrk.body = "foo=bar&baz=quux" wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
-
为每次request更换一个参数
通过在request方法中随机生成1~10000000之间的uid,使得请求中的uid参数随机。
1 2 3 4 5
request = function() uid = math.random(1, 10000000) path = "/test?uid=" .. uid return wrk.format(nil, path) end
-
每次请求之前延迟10ms
1 2 3
function delay() return 10 end
-
每个线程要先进行认证,认证之后获取token以进行压测
在没有token的情况下,先访问/authenticate认证。认证成功后,读取token并替换path为/resource。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
token = nil path = "/authenticate" request = function() return wrk.format("GET", path) end response = function(status, headers, body) if not token and status == 200 then token = headers["X-Token"] path = "/resource" wrk.headers["X-Token"] = token end end
-
压测支持HTTP pipeline的服务
通过在init方法中将三个HTTP request请求拼接在一起,实现每次发送三个请求,以使用HTTP pipeline。
1 2 3 4 5 6 7 8 9 10 11 12
init = function(args) local r = {} r[1] = wrk.format(nil, "/?foo") r[2] = wrk.format(nil, "/?bar") r[3] = wrk.format(nil, "/?baz") req = table.concat(r) end request = function() return req end