性能测试
一、性能测试是什么
性能测试的核心目标是回答一个问题:系统能扛多大压力,瓶颈在哪里?
它不是简单地"压一下看看",而是通过科学的方法,找到系统的能力边界和优化方向。
二、测试类型(按目的分)
| 类型 | 目的 | 做法 | 典型产出 |
|---|---|---|---|
| 基准测试 | 摸清系统正常能力 | 单接口/单场景,逐步加压 | 最大 TPS、RT 基线 |
| 负载测试 | 验证能否满足预期目标 | 按目标值压(如 1000 TPS) | 通过/不通过 |
| 压力测试 | 找系统极限,什么时候崩 | 持续加压直到崩溃 | 极限值、崩溃表现 |
| 稳定性测试 | 长时间运行有无问题 | 中等压力跑 2~24 小时 | 内存泄漏、GC 问题 |
| 容量测试 | 当前配置能支撑多少用户 | 阶梯加压 + 资源监控 | 容量规划建议 |
| 浪涌测试 | 突发流量能否扛住 | 瞬间拉高再降低 | 系统恢复能力 |
怎么选择测试类型?
1 | 新系统上线前 → 基准测试 + 负载测试 |
三、测试场景(按业务分)
3.1 基础场景
| 场景 | 说明 | 适用情况 |
|---|---|---|
| 单接口测试 | 对单个 API 压测 | 性能摸底、问题定位 |
| 单业务流程 | 完整链路(如下单=查库存→创建订单→扣款) | 链路性能验证 |
3.2 进阶场景
| 场景 | 说明 | 关键点 |
|---|---|---|
| 混合场景 | 模拟真实流量比例 | 接口比例要贴近生产 |
| 秒杀/抢购 | 瞬间高并发打同一资源 | 集合点、库存一致性、限流 |
| 大数据量 | 处理大量数据(导出、批量) | 单请求处理能力、超时 |
| 长连接 | WebSocket、消息推送 | 连接数上限、心跳、断连 |
| 文件上传下载 | 大文件传输 | 带宽、超时、断点续传 |
3.3 混合场景设计示例
1 | 电商网站真实流量比例: |
混合场景的价值:单接口都没问题,混合起来可能有资源竞争。
四、性能指标体系
4.1 业务指标(用户视角)
| 指标 | 全称 | 含义 | 关注点 |
|---|---|---|---|
| RT | Response Time | 响应时间 | P90/P99 比平均值重要 |
| TPS | Transactions Per Second | 每秒事务数 | 业务处理能力 |
| QPS | Queries Per Second | 每秒请求数 | 接口吞吐量 |
| 并发数 | Concurrency | 同时在处理的请求数 | 系统承载能力 |
| 错误率 | Error Rate | 失败请求占比 | 压力大了是否报错 |
| 吞吐量 | Throughput | 单位时间处理的数据量 | 网络/IO 能力 |
响应时间的正确理解
1 | 平均 RT = 100ms ← 看起来不错? |
TPS vs QPS
1 | TPS:一个事务可能包含多个请求(下单=查库存+扣款+创建订单) |
4.2 系统资源指标(服务器视角)
| 指标 | 监控命令 | 瓶颈信号 | 可能原因 |
|---|---|---|---|
| CPU | top, vmstat |
持续 > 80% | 计算密集、死循环、GC |
| 内存 | free, top |
持续上涨不释放 | 内存泄漏、缓存过大 |
| 磁盘 I/O | iostat, iotop |
iowait 高、util 100% | 大量读写、日志过多 |
| 网络 | iftop, netstat |
带宽打满、连接数耗尽 | 数据量大、连接泄漏 |
CPU 指标详解
1 | %user - 用户态 CPU(应用代码) |
内存指标详解
1 | used - 已使用内存 |
4.3 中间件指标(组件视角)
数据库(MySQL)
| 指标 | 含义 | 关注点 |
|---|---|---|
| QPS/TPS | 查询和事务数 | 数据库压力 |
| 慢查询数 | 超过阈值的 SQL | 需要优化的 SQL |
| 连接数 | 当前连接 / 最大连接 | 连接池是否够用 |
| 锁等待 | 行锁、表锁等待时间 | 并发冲突 |
| 缓冲池命中率 | Buffer Pool Hit Ratio | 内存是否够用 |
Redis
| 指标 | 含义 | 关注点 |
|---|---|---|
| 命中率 | Hit / (Hit + Miss) | 缓存有效性 |
| 内存使用 | used_memory | 是否接近上限 |
| 连接数 | connected_clients | 连接池配置 |
| 阻塞 Key | blocked_clients | 慢操作 |
消息队列(Kafka/RabbitMQ)
| 指标 | 含义 | 关注点 |
|---|---|---|
| 堆积量 | 未消费消息数 | 消费者是否跟得上 |
| 生产速率 | 每秒写入消息数 | 生产压力 |
| 消费速率 | 每秒消费消息数 | 消费能力 |
| 延迟 | 消息从生产到消费的时间 | 实时性 |
4.4 JVM 指标(Java 应用)
| 指标 | 含义 | 关注点 |
|---|---|---|
| 堆内存 | Heap 使用量 | 是否频繁接近上限 |
| GC 次数 | Young GC / Full GC | Full GC 频繁说明有问题 |
| GC 时间 | 每次 GC 耗时 | 影响 RT |
| 线程数 | 活跃线程数量 | 线程池是否够用 |
五、常用工具
5.1 压测工具
| 工具 | 特点 | 适用场景 |
|---|---|---|
| JMeter | GUI + 脚本,功能全 | 复杂业务场景、协议多 |
| Locust | Python 编写脚本 | 开发友好、灵活 |
| wrk | 命令行,性能极高 | 简单接口、极限压测 |
| ab | Apache 自带,简单 | 快速验证 |
| k6 | JS 脚本,现代化 | CI/CD 集成 |
| Gatling | Scala,报告漂亮 | 自动化、报告要求高 |
5.2 监控工具
| 工具 | 用途 |
|---|---|
| Prometheus + Grafana | 指标采集 + 可视化 |
| node_exporter | 主机资源监控 |
| cAdvisor | 容器监控 |
| Arthas | Java 应用诊断 |
| perf / FlameGraph | CPU 火焰图 |
5.3 分析工具
| 工具 | 用途 |
|---|---|
| 慢查询日志 | 定位慢 SQL |
| Explain | 分析 SQL 执行计划 |
| jstack | Java 线程 dump |
| jmap | Java 内存 dump |
| MAT | 内存泄漏分析 |
六、性能测试流程
6.1 标准流程
1 | 1. 需求分析 |
6.2 瓶颈定位思路
1 | RT 变长 / TPS 上不去 |
七、Q&A
7.1 基础问题
Q:你们性能测试关注哪些指标?
三层:业务指标(RT、TPS、错误率)、系统资源(CPU、内存、IO、网络)、中间件指标(数据库、缓存)。重点是把指标放在同一时间轴上看,找到瓶颈。
Q:RT 看平均值还是 P99?
P99 更重要。平均值会被大量正常请求拉低,掩盖长尾问题。比如平均 100ms,但 P99 是 2s,说明有 1% 用户体验很差。
Q:TPS 和 QPS 的区别?
TPS 是事务,一个事务可能包含多个请求;QPS 是纯请求数。接口压测一般说 QPS,业务压测说 TPS。
7.2 场景问题
Q:你们预估的 QPS 是怎么得出的?
两种方法:1)看生产监控历史峰值;2)业务推算:日活 × 人均请求数 ÷ 集中时段秒数,再乘 2~3 倍余量。
Q:混合场景怎么设计?
分析生产日志或埋点数据,统计各接口调用比例,按比例配置并发。比如浏览 60%、搜索 25%、下单 5%。
Q:秒杀场景怎么测?
用集合点让请求同时发出,关注:1)限流是否生效;2)库存一致性;3)系统是否雪崩。
Q:稳定性测试发现过什么问题?
内存泄漏(内存持续上涨不释放)、连接泄漏(连接数持续增长)、GC 时间变长、RT 逐渐上涨。
7.3 定位问题
Q:TPS 上不去,怎么排查?
先看资源:CPU、内存、IO 哪个高。如果都不高,看数据库慢查询、连接池、锁竞争、外部依赖。
Q:CPU 高怎么定位?
看是 user 高还是 iowait 高。user 高用火焰图找热点代码;iowait 高说明磁盘是瓶颈。
Q:内存泄漏怎么定位?
多次 dump 内存快照,用 MAT 对比,看哪些对象持续增长。
八、实战检查清单
测试前
- 明确测试目标(TPS、RT、错误率要求)
- 测试环境配置记录(CPU、内存、带宽)
- 监控部署完成(能看到实时数据)
- 测试数据准备(数量级合理)
- 脚本调试通过(单次请求正常)
测试中
- 逐步加压,不要一上来就拉满
- 实时观察监控,发现异常及时记录
- 每轮测试记录:并发数、TPS、RT、错误率、资源使用
- 出现拐点时停下来分析
测试后
- 整理各轮数据,画趋势图
- 定位瓶颈点
- 输出测试报告
- 提出优化建议
九、附录:常用命令速查
1 | # CPU |
总结
性能测试的本质是:给系统施加压力,观察表现,找到瓶颈,指导优化。
记住这个思考框架:
1 | 目标 → 场景 → 指标 → 执行 → 分析 → 优化 |
不是为了压测而压测,而是为了回答业务问题:系统能不能扛住?扛不住的话问题在哪?