压力测试工具wrk安装、使用
目录
一.wrk介绍
1.适用操作系统
2.名字的寓意
3.诞生的背景
二.安装wrk
1.执行安装命令
2.验证是否安装成功
三.实战:压测一个本地接口,并分析
1.先本地启动自己的项目,用Apifox调用一下本地接口,查看是否可调通
2.在本地终端(任意目录),执行wrk命令压测该接口
3.查看返回结果(压测报告)
4.注意
四.带参数的接口压测时,wrk命令怎么写?
1.GET 请求带参数
2.POST 请求带参数
3.总结建议
五.专业名词解释
一.wrk介绍
1.适用操作系统
wrk这款工具,在Linux操作系统上是完美支持的,而Windows、MacOS上也可以用,但是安装时相对较麻烦。
因此我们直接在Linux上安装、使用即可。
2.名字的寓意
wrk 这个名字并没有复杂的深层含义,它其实就是英文单词"work"(工作)去掉元音字母 "o" 后的简写。
这种命名方式在程序员和极客文化中非常流行,既简洁又形象地表达了这款工具的核心使命——让服务器“干活”。它被设计用来给 Web 服务器施加高强度的负载,通过模拟大量的并发请求,来测试服务器在繁重“工作”压力下的吞吐量、延迟以及稳定性表现。
3.诞生的背景
wrk 由开发者 Will Glozer 在 2012 年首次发布,它的诞生主要是为了解决早期 HTTP 压测工具在现代高并发场景下“力不从心”的问题。
- 老工具的瓶颈:在 wrk 出现之前,行业内最经典的压测工具是诞生于 1996 年的 ApacheBench(简称 ab)。但 ab 默认使用较老的 HTTP/1.0 协议,不支持 Keep-Alive(长连接),且采用传统的阻塞式 I/O 模型。这导致它的单机并发能力很弱,通常压到几千并发就会遇到瓶颈,无法真实反映现代 Web 服务的性能极限。
- 现代架构的崛起:随着 Nginx、Node.js 等基于异步事件驱动(如 Linux 的 epoll、BSD/macOS 的 kqueue)的高性能服务器软件兴起,行业急需一款能够真正榨干多核 CPU 性能、产生极高负载的压测利器。
- wrk 的破局:在这样的背景下,wrk 应运而生。它底层采用 C 语言编写,结合了多线程设计与高效的异步事件驱动模型。这使得它在单台多核机器上就能轻松模拟出上万的并发连接和数万甚至更高的 QPS(每秒请求数),其压测能力通常比老工具 ab 高出几倍到几十倍,迅速成为了开发者、运维和性能测试人员的首选基准测试工具。
二.安装wrk
1.执行安装命令
注意:以下命令是针对Linux的,支持所有内核(比如centos、ubuntu等等)。
# 1. 安装编译所需的依赖工具 sudo apt-get install build-essential libssl-dev git -y # 2. 从代码仓库拉取 wrk 源码 git clone https://github.com/wg/wrk.git wrk # 3. 进入目录并编译 cd wrk make # 4. 将编译好的程序移动到系统命令目录,使其全局可用 sudo cp wrk /usr/local/bin
2.验证是否安装成功
wrk --version效果展示:
如图,出现了wrk的版本号,就说明wrk安装成功了。
三.实战:压测一个本地接口,并分析
1.先本地启动自己的项目,用Apifox调用一下本地接口,查看是否可调通
2.在本地终端(任意目录),执行wrk命令压测该接口
wrk -t4 -c100 -d10s --latency http://localhost:8080/mytest/test01命令解读:
参数 含义 形象解读 -t4 启动 4 个线程 派出 4 个“攻击小分队”去执行任务 -c100 保持 100 个 TCP 连接 小分队一共维持 100 条通往服务器的“专用通道” -d10s 持续压测 10 秒 疯狂发请求 10 秒钟,时间一到立刻收手 --latency 打印详细延迟统计 记录 50%、90%、99% 等请求的耗时分布,判断稳不稳定 URL地址 目标接口地址 默认发起 GET 请求,直接访问你的 Spring Boot 接口
注意:由于我们之前安装了wrk,并且把编译好的wrk文件传到了/usr/local/bin目录,所以我们在任一一个目录都能执行wrk命令。
3.查看返回结果(压测报告)
解读:
核心指标 具体数据 解读与意义 吞吐量 (QPS) 10476.42Requests/sec 性能极强。你的接口每秒能稳定处理超过 1 万个请求。 平均延迟 (Avg Latency) 9.55 ms 响应极快。服务器处理单个请求平均只需不到 10 毫秒。 延迟分布 (P99 Latency) 20.13 ms 极其稳定。即使是最慢的 1% 请求,也在 20 毫秒内完成,无明显卡顿。 网络流量 (Transfer/sec) 3.85 MB 10 秒内共传输 38.53MB 数据,平均每秒产生约 3.85MB 的网络流量。 请求总量与成功率 104897 次请求,0 错误 高度可靠。全程没有出现连接失败、读取错误或超时(Socket errors 为 0)。 并发压力配置 4 线程 / 100 连接 在 100 个并发连接的负载下,系统运行游刃有余,CPU 和网络均未出现瓶颈。
4.注意
- 由于我们的测试接口,只是简单的返回了一个“测试成功”字符串,所以压测结果肯定漂亮,因为没啥具体的业务逻辑(比如数据库连接、业务数据计算等耗时行为),所以压测结果好是必然的
- 我们这个测试接口,没有入参,所以我们用wrk进行压测时,没有传参数。但后续带参数的接口在进行压测时,就需要传参数了,这个我们本文中没讲,下面会讲解一下。
四.带参数的接口压测时,wrk命令怎么写?
带参数的接口压测,主要分两种情况:GET 请求(参数拼接在 URL 后面)和POST 请求(参数放在请求体中)。
wrk 处理带参数的请求,通常有两种写法:
- 直接在命令中写死参数(适合测试固定参数的接口)。
- 使用 Lua 脚本动态生成参数(适合模拟真实用户,每次请求的参数都不一样,比如随机用户 ID)。
下面为你详细拆解这两种情况的写法:
1.GET 请求带参数
- 情况 A:参数固定(最简单,直接在 URL 后拼接)
如果你的接口是
http://localhost:8080/mytest/getUser?id=1001,直接在命令里写上完整的 URL 即可:wrk -t4 -c100 -d10s --latency "http://localhost:8080/mytest/getUser?id=1001"
- 情况 B:参数动态变化(需要写简单的 Lua 脚本)
如果你想测试不同的
id(比如 1 到 10000 的随机用户),就需要用到-s参数加载 Lua 脚本。
首先,新建一个名为get_user.lua的文件,内容如下:
-- get_user.lua request = function() -- 随机生成 1 到 10000 之间的 id local id = math.random(1, 10000) -- 拼接动态的 URL 路径 local path = "/mytest/getUser?id=" .. id -- 返回格式化后的 GET 请求 return wrk.format("GET", path) end然后在终端执行命令:
wrk -t4 -c100 -d10s --latency -s get_user.lua http://localhost:8080(注意:使用脚本时,URL 只需要写基础的域名和端口,具体的路径在脚本里拼接)
2.POST 请求带参数
POST 请求的参数通常放在请求体(Body)里,并且需要指定请求头(如
Content-Type)。
- 情况 A:参数固定(直接在命令中指定 Header 和 Body)
wrk 提供了
--script(或-s) 来直接指定简单的 POST 信息,但更推荐直接用 Lua 脚本来写,这样更清晰且容易扩展。
- 情况 B:参数固定或动态(推荐使用 Lua 脚本)
假设你的接口是
http://localhost:8080/mytest/addUser,需要传入 JSON 格式的参数{"name": "张三", "age": 18}。
新建一个名为post_user.lua的文件,内容如下:
-- post_user.lua -- 设置请求方法为 POST wrk.method = "POST" -- 设置请求体(如果是 JSON,直接写 JSON 字符串) wrk.body = '{"name":"张三","age":18}' -- 设置请求头,告诉服务器发送的是 JSON 数据 wrk.headers["Content-Type"] = "application/json"执行命令:
wrk -t4 -c100 -d10s --latency -s post_user.lua http://localhost:8080/mytest/addUser- 进阶:如果你想每次 POST 的参数也是随机的,可以把
post_user.lua改成这样:
-- post_user_random.lua request = function() -- 随机生成年龄 local age = math.random(18, 60) -- 拼接动态的 JSON 字符串 local body = string.format('{"name":"用户%d","age":%d}', math.random(1, 1000), age) -- 组装并返回请求 return wrk.format("POST", nil, {["Content-Type"] = "application/json"}, body) end3.总结建议
- 如果你只是偶尔测试一个带固定参数的接口,直接把参数拼在 URL 后面(GET)或者写个最简单的 Lua 脚本(POST)就行。
- 如果你要模拟真实的高并发场景(比如秒杀、随机查询不同用户),强烈建议花几分钟学一下上面Lua 脚本动态生成参数的写法,这在后续的真实项目压测中非常实用!
你可以先拿你现有的带参接口,试试第一种最简单的“直接拼接 URL”的方法跑一下看看效果。
五.专业名词解释
| 专业名词 | 全称与命名由来 | 这个指标意味着什么 |
|---|---|---|
| QPS | Queries Per Second(每秒查询率) 也常被称为RPS(Requests Per Second)。之所以叫“每秒查询”,是因为它衡量的是服务器在一秒钟内能成功响应并处理完多少个请求(查询)。 | 代表系统的“吞吐量”或“抗压能力”。 数值越高,说明你的接口每秒能接待的客户越多,系统越强悍。 |
| Latency | 延迟 / 响应时间 指从你发出请求开始,到服务器处理完并把结果送回给你,这中间所花费的时间。 | 代表系统的“反应速度”。 数值越低越好。比如 9ms 就比 200ms 快得多,用户几乎感觉不到等待。 |
| Stdev | Standard Deviation(标准差) 这是一个统计学名词,用来衡量数据的“波动幅度”或“离散程度”。 | 代表系统性能的“稳定性”。 数值越低,说明每次请求的耗时都很接近,系统发挥很稳;如果 Stdev 很大,说明接口时而快、时而卡,极不稳定。 |
| Max | Maximum(最大值) 在所有请求中,耗时最长的那一次所花费的时间。 | 代表系统可能出现过的“最差表现”。 如果 Avg(平均值)很低但 Max 极高,说明系统偶尔会出现严重的卡顿(比如偶尔卡了 5 秒),需要警惕。 |
| P99 / 99% | 99th Percentile(99分位值) 意思是:把所有的请求按耗时从短到长排队,排在第 99% 位置的那个请求的耗时是多少。 | 代表“绝大多数用户的真实体验”。 比如 P99 是 20ms,说明99%的用户都能在 20ms 内得到响应。它比平均值更能反映真实情况,排除了极少数极端异常的干扰。 |
| Threads | 线程 可以理解为 wrk 派出的“攻击小分队”的数量。 | 代表压测工具的“进攻火力配置”。 线程越多,wrk 发起请求的能力越强(但如果线程过多,可能会受限于你本地电脑的 CPU 性能)。 |
| Connections | 连接数(并发数) 指 wrk 与你的服务器之间同时保持的 TCP 通道数量。 | 代表同时向服务器施压的“并发量”。 连接数越高,模拟的同时在线用户就越多,服务器承受的压力也就越大。 |
以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~~~
