

API 性能测试工具 WRK
source link: https://liqiang.io/post/961e61f4-928b-4923-ba4c-bf5a684efbf5?lang=ZH_CN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

All Posts
API 性能测试工具 WRK
@POST· 2021-07-20 18:00 · 48 min read
wrk 介绍
在了解 wrk 之前,我对性能测试的了解一直局限在 ab(Apache Benchmark) 上,我印象中 ab 的功能比较简单,就是简单地压测给定的 API,然后看并发量是多少,这在一些全都是 get 的场景下倒是没什么问题,但是如果要涉及一些更复杂的测试就比较难搞了,所以我就了解了一下,然后看到别人安利了一下 wrk,所以就顺便记录一下关于 wrk 的东西。
wrk 的基本功能其实也很 ab 很类似,可以简单地做一些 GET 的大量请求,然后算 QPS(Request Per Seconds) 和 RT(Response Time) 之类的,但是 wrk 不能直接执行 POST 请求(ab 可以)。所以,这里就需要进一步了解到 wrk 还有一个比较重要的功能:它支持通过 lua 脚本来做扩展,通过 lua 脚本,你可以做到:
- 执行一个自定义的 POST 请求
- 先调用一个登陆 API 拿到认证信息后,再给下一个测试 API 使用;
- 通过设置不同的 API 同时测试,更全面地测试并发能力;
- 调用完一个 API 后,等待一段时间再测试(这个 API 可能比较特殊)
- 自定义测试结果的展示效果
这些都是 lua 脚本的扩展功能,在这方便,会比 ab 会好用很多。有意思的一件事情是,如果你去找 wrk,你还会发现一个 wrk2 的东西,它其实是 wrk 的修改版本,作者自己加入了一个所谓的 constant throughput 的功能,其实就是不测试 QPS 了,而是保持一定的 QPS,然后看 server 端的响应速度如何,表现怎么样,所以,一般情况下,我是不需要 wrk2 的。
基本功能演示
光说不练假把式,所以这里我只能演示一个简单的 GET 请求,其实就是看下 wrk 是如何执行这两个简单的操作的,至于 POST 请求,我需要在下一章节 扩展功能 中介绍:
一个 GET 请求
[[email protected]]# wrk -t1 -c2 -d5s http://google.com
Running 5s test @ http://google.com
1 threads and 2 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 17.33ms 17.71ms 150.59ms 94.35%
Req/Sec 138.00 30.28 180.00 84.00%
692 requests in 5.03s, 356.81KB read
Requests/sec: 137.50
Transfer/sec: 70.90KB
这里我很抱歉拿 google.com 来作为一个演示的例子,但是这确实是工作的,这里先解析一下输入的参数分别是什么意思,这很重要:
-t1
: 表示开启一个线程来进行测试-c2
: 表示开启 2 个并发进行测试-d5s
: 表示执行测试 5s,从结果中可以看出,实际上执行时间是 5.03 秒,说明还是受控的- url: 这就是要进行测试的 url 了
扩展功能演示
lua 脚本执行逻辑
wrk 的 POST 请求不能直接通过命令行的参数执行,所以需要通过 lua 脚本的方式来运行,再看 lua 的编写和执行之前,先来了解一些 wrk 的 lua 的上下文概念:
- 在 wrk 中,每个线程的 lua 上下文是独立的,不会互相干扰,这对于编写 lua 脚本有意义
- 在 wrk 中,lua 脚本可以分为三部分,你可以只使用其中某一阶段的自定义脚本,也可以全都定义,这三个阶段分别是:
- 启动阶段(setup):每个线程启动时,会且整个生命周期只会执行一遍
- 运行阶段(start):执行测试的时候,lua 线程会调用里面的自定义函数
- 结束阶段(stop):测试完毕之后,lua 线程会调用里面的函数,一般用于控制输出内容格式
lua 脚本框架
看完理论部分,解析来看下,每个阶段对应的 lua 框架是什么样的,也就是说,wrk 规定的 lua 脚本应该怎么写。
lua 线程启动之后,就会调用这个阶段的自定义函数,这个节点只有一个自定义函数:
[[email protected]]# cat setup.lua
local counter = 1
function setup(thread)
thread:set("id", counter)
table.insert(threads, thread)
counter = counter + 1
end
可以看到,在启动阶段,你可以修改 setup
函数的内容作为自定义的启动内容,里面你可以修改这个线程相关的信息,例如修改线程的变量,修改线程的 server 地址之类的,一般都不用修改,如果你想修改的话,这里有一些参数的函数可以供你使用:
运行阶段是 wrk 的核心部分,在这一部分,你可以有多个函数可以定义,分别是:
函数名称 作用 function init(args) lua 线程进入运行阶段时,会执行一遍,后续就不执行了,你可以在这个阶段做一些请求的初始化之类的 function delay() lua 线程每次发起请求之前都会调用一次这个 function request() lua 线程会通过这个函数的响应作为请求进行发送 function response(status, headers, body) lua 线程会将每次请求的响应作为参数调用这个函数这里给一个示例每个阶段的代码是怎么写的:
[[email protected]]# cat running.lua
function init(args)
requests = 0
responses = 0
local msg = "thread %d created"
print(msg:format(id))
end
function delay()
return math.random(10, 50)
end
function request()
requests = requests + 1
return wrk.request()
end
function response(status, headers, body)
responses = responses + 1
end
这就是一个简单的示例了,在示例里面,这里每个请求都延迟了 10-50 毫秒,然后在请求之前会记录一下请求数,请求成功之后也会记录一下请求的响应数量。
在结束之后,lua 允许你定义你自己的处理结果,在这里,你可以自定义你的输出格式,如果你不喜欢默认的输出格式的话,这里也只有一个你需要自己定义的函数:
[[email protected]]# cat stop.lua
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
特别的例子
如果你只想修改一下 request 就好了,其他都不想自定义,那么你可以直接在 lua 里面写 request 里面的函数,不用 return,也不用写函数定义,下面个 POST 的示例就是这种情况。
POST 请求
如果按照我们上一小节介绍的 lua 框架来说,我们可以在 request () 里面定义请求的格式,将请求方式定义为 POST 就可以了,但是,最后我也提了一下,wrk 考虑到了这种场景的常见性,所以讲这个 feature 简化成你只需要写一段脚本就可以了,不用在定义 function 和 return 了,例如这样就可以了:
[[email protected]]# cat post.lua
wrk.method = "POST"
wrk.body = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
这就是一个 POST 的示例了,然后通过 wrk 加载这个 lua 脚本运行:
[[email protected]]# wrk -c3 -d1s -t2 -s ./scripts/post.lua http://localhost:5000/api/v1/login
lua 辅助函数
函数 解释 wrk.format(method, path, headers, body) 这个函数通常用于 request () 阶段返回 request 对象
done 的参数属性
done(summary, latency, requests)
里面记录了性能测试的很多数据,包含的字段如下:
一个复杂的例子
[[email protected]]# cat pipeline.lua
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
Recommend
-
196
wrk - a HTTP benchmarking tool wrk is a modern HTTP benchmarking tool capable of generating significant load when run on a single multi-core CPU. It combines a multithreaded design with scalable event notification systems such as epoll an...
-
20
没有最好,只有最合适。 如今,越来越多的公司正在向DevOps的方向左转,以实现持续集成和持续部署开发。这意味着我们的反馈需要比以往更快,以便确定我们的应用程序是否准备好交付。这就是API测试如此重要的原因,以及为什么应将其...
-
7
← 上一篇 下一篇 → WRK:一个可编程的HTTP性能测试工具 发表于
-
6
Web服务压测神器wrk 2020-01-02 分类:工具 阅读(4236) 评论(2)
-
8
本文首发:最好用的七大顶级 API 接口测试工具 - 卡...
-
11
V2EX › Go 编程语言 给 go-wrk 安上了 JavaScript 脚本支持 ryanking8215 · 7 小时 25 分钟...
-
11
Wrk secures $43M to help businesses automate common workflows Image Credit: Wrk An enduring feature of the pandemic will be the increased d...
-
8
ab、wrk、JMeter、Locust压测工具的并发模型 发表于 2020-11-06...
-
8
Http 压测工具 -- wrk Tools | Apr 7, 2018 | Http
-
10
Benchmarking Your HTTP Service Using wrk 2022-08-10 tools 444 words 3 mins read 18 times read As a machi...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK