3. 性能测试工具:JMeter基础、wrk使用、ab压力测试、Locust框架、Gatling介绍
做性能测试这么多年,我接触过的工具少说也有十几种。说实话,没有哪个工具是万能的。每个工具都有自己的脾气,关键是你得知道在什么场景下用它最合适。
今天我就把这五个主流工具掰开揉碎了讲一讲。你想想看,要是能把它们各自的优缺点摸透,以后遇到性能测试需求,你就能快速选出趁手的家伙。
3.1 JMeter基础
JMeter 是我用得最多的工具,没有之一。它是个纯 Java 写的开源工具,Apache 家的。我第一次用它是在一个电商项目上,那时候系统刚上线,用户一多就卡得要命。嗯,JMeter 帮我找到了瓶颈。
核心概念
- 线程组:模拟用户数。我习惯把线程数设成目标并发数,比如 100 个线程就是 100 个虚拟用户
- 取样器:发什么请求。HTTP 请求、JDBC 请求、FTP 请求,都行
- 监听器:看结果。聚合报告、图形结果、表格结果,我最常用的是聚合报告
- 断言:判断请求对不对。比如响应码是不是 200,响应体里有没有某个关键字
一个简单的 HTTP 测试计划
// 测试计划结构
Test Plan
├── Thread Group (100 users, ramp-up 10s, loop 5)
│ ├── HTTP Request Defaults
│ │ └── Server: api.example.com
│ ├── HTTP Request
│ │ ├── Path: /api/users
│ │ └── Method: GET
│ ├── Response Assertion
│ │ └── Pattern: "status": "ok"
│ └── View Results Tree
└── Aggregate Report
jmeter -n -t test.jmx -l result.jtl。GUI 模式本身就会吃掉不少资源,影响测试结果。
3.2 wrk 使用
wrk 是个轻量级的 HTTP 压测工具,用 C 写的。它最大的特点就是快,能压出很高的并发。我一般在排查单接口性能问题时用它,几秒钟就能出结果。
基本用法
# 基本压测:12个线程,400个连接,持续30秒
wrk -t12 -c400 -d30s http://api.example.com/users
# 带请求体的 POST 请求
wrk -t4 -c100 -d10s -s post.lua http://api.example.com/login
# post.lua 内容
wrk.method = "POST"
wrk.body = '{"username":"test","password":"123456"}'
wrk.headers["Content-Type"] = "application/json"
输出解读
| 指标 | 含义 | 我关注的点 |
|---|---|---|
| Latency | 延迟分布 | 看 Avg 和 P99,P99 太高说明有长尾请求 |
| Req/Sec | 每秒请求数 | 这就是吞吐量,越高越好 |
| Transfer/Sec | 每秒传输量 | 带宽够不够,看这个就知道 |
3.3 ab 压力测试
ab 是 Apache 自带的压测工具,全称 ApacheBench。它比 wrk 还轻量,安装 Apache 或 Nginx 时一般都会带上。我偶尔用它做快速验证,比如刚部署完一个新接口,想看看能不能跑通。
常用命令
# 100个请求,10个并发
ab -n 100 -c 10 http://api.example.com/users
# 带 Header 的请求
ab -n 1000 -c 50 -H "Authorization: Bearer token123" http://api.example.com/profile
关键输出指标
- Requests per second:每秒请求数,核心指标
- Time per request:平均每个请求耗时,分两种:所有请求平均、并发请求平均
- Failed requests:失败的请求数,如果大于 0,说明系统扛不住了
我个人经验:ab 适合做单机、短时间的压测。它不支持复杂的场景编排,比如登录后获取 token 再请求其他接口,ab 就搞不定了。这时候得用 JMeter 或 Locust。
3.4 Locust 框架
Locust 是用 Python 写的,最大的亮点是可以用代码定义用户行为。我特别喜欢它的 Web 界面,跑压测的时候能实时看到 RPS、响应时间、失败率,一目了然。
一个简单的 Locust 脚本
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5) # 用户等待时间 1-5 秒
@task(3) # 权重 3
def view_users(self):
self.client.get("/api/users")
@task(1) # 权重 1
def create_user(self):
self.client.post("/api/users", json={
"name": "test",
"email": "test@example.com"
})
运行方式
# 启动 Locust Web 界面
locust -f locustfile.py --host=http://api.example.com
# 无界面模式(适合 CI/CD)
locust -f locustfile.py --host=http://api.example.com --headless -u 100 -r 10 --run-time 1m
wait_time,结果所有用户都在疯狂发请求,直接把测试环境的数据库打崩了。记住,模拟真实用户行为时,一定要加思考时间。
3.5 Gatling 介绍
Gatling 是基于 Scala 和 Akka 的高性能压测工具。它的报告生成能力是我见过最强的,图表特别漂亮。我一般用它来做正式的、需要出报告的性能测试。
一个 Gatling 脚本示例
import io.gatling.core.Predef._
import io.gatling.http.Predef._
class UserSimulation extends Simulation {
val httpProtocol = http
.baseUrl("http://api.example.com")
.acceptHeader("application/json")
val scn = scenario("User Scenario")
.exec(http("Get Users")
.get("/api/users")
.check(status.is(200)))
.pause(2) // 思考时间 2 秒
.exec(http("Create User")
.post("/api/users")
.body(StringBody("""{"name":"test"}"""))
.check(status.is(201)))
setUp(
scn.inject(
rampUsers(100).during(10), // 10秒内启动100个用户
constantUsersPerSec(20).during(60) // 持续60秒,每秒20个用户
)
).protocols(httpProtocol)
}
Gatling 的优势
- 高性能:基于 Akka 的异步模型,能压出很高的并发
- 报告精美:HTML 报告包含响应时间分布、吞吐量趋势、活跃用户数等
- DSL 清晰:Scala 的 DSL 写起来很流畅,可读性强
3.6 工具对比总结
| 工具 | 语言 | 适用场景 | 我的推荐 |
|---|---|---|---|
| JMeter | Java | 复杂场景、分布式压测 | 团队通用,功能最全 |
| wrk | C | 单接口快速压测 | 开发自测首选 |
| ab | C | 简单验证 | 临时用用,别太依赖 |
| Locust | Python | 用户行为模拟 | Python 团队首选 |
| Gatling | Scala | 正式压测、报告输出 | 追求报告质量的团队 |
3.7 知识体系图
好了,这五个工具就讲完了。说实话,工具只是手段,关键是你得理解系统的行为。我见过有人用 JMeter 压了一整天,结果发现瓶颈在数据库连接池上,跟工具一点关系都没有。所以,别光顾着学工具,多想想系统到底哪里慢。
想要更多资料,联系可可