关键字:wrk,压力测试
wrk是基于事件机制的高性能 HTTP 压力测试工具。
wrk 负载测试时可以运行在一个或者多核CPU,wrk 结合了可伸缩的事件通知系统 epoll 和 kqueue 等多线程设计思想。wrk 不仅能测试单条 URL,还能通过
LuaJIT
脚本实现对不同的 URL 和参数、请求内容进行测试。
参数
|
|
安装
macOS brew
1brew install wrkCentOS
1234567sudo yum groupinstall 'Development Tools'sudo yum install -y openssl-devel gitgit clone https://github.com/wg/wrk.git wrkcd wrkmake# move the executable to somewhere in your PATHsudo cp wrk /somewhere/in/your/PATHUbuntu
123456sudo apt-get install build-essential libssl-dev git -ygit clone https://github.com/wg/wrk.git wrkcd wrksudo make# move the executable to somewhere in your PATH, ex:sudo cp wrk /usr/local/bin
普通示例
|
|
使用Lua脚本个性化wrk压测
wrk支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua运行环境。
请求方式,命令中添加参数-s <lua path>
:
|
|
启动阶段
|
|
在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。
|
|
运行阶段
|
|
init由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;
|
|
delay在每次发送request之前调用,如果需要delay,那么delay相应时间;
|
|
request用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;
|
|
reponse在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;
结束阶段
|
|
该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。
自定义脚本中可访问的变量和方法
变量: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头。
123wrk.method = "POST"wrk.body = "foo=bar&baz=quux"wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"为每次request更换一个参数
通过在request方法中随机生成1~10000000之间的uid,使得请求中的uid参数随机。
12345request = function()uid = math.random(1, 10000000)path = "/test?uid=" .. uidreturn wrk.format(nil, path)end每次请求之前延迟10ms
123function delay()return 10end每个线程要先进行认证,认证之后获取token以进行压测
在没有token的情况下,先访问/authenticate认证。认证成功后,读取token并替换path为/resource。
1234567891011121314token = nilpath = "/authenticate"request = function()return wrk.format("GET", path)endresponse = function(status, headers, body)if not token and status == 200 thentoken = headers["X-Token"]path = "/resource"wrk.headers["X-Token"] = tokenendend压测支持HTTP pipeline的服务
通过在init方法中将三个HTTP request请求拼接在一起,实现每次发送三个请求,以使用HTTP pipeline。
123456789101112init = 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)endrequest = function()return reqend