接口压测案例
返回接口压测案例
一、为什么要先做接口级案例
对于刚接触性能测试的 Java 后端工程师来说,最容易上手的是接口压测。
原因很简单:
- 范围小
- 依赖少
- 容易复现
- 结果好分析
接口压测适合回答这样的问题:
- 单个接口能扛多少流量
- 在预期流量下是否达标
- 性能瓶颈大概在哪
二、案例背景
假设有一个订单查询接口:
GET /api/order/detail?id=10001
业务要求:
- 日常 QPS 约 300
- 活动峰值 QPS 约 800
- P95 响应时间小于 200ms
- 错误率低于 0.1%
这个接口会做几件事:
- 校验用户身份
- 查询订单主表
- 查询订单明细
- 查询支付状态
这已经是比较典型的 Java 后端查询接口。
三、压测目标
在正式压测前,先把目标写清楚。
本次目标可以定成:
- 验证接口在 800 QPS 下是否达标
- 找出接口的最大稳定吞吐量
- 判断瓶颈在应用、数据库还是缓存
这里有一个原则:
压测目标必须和业务要求对应,不能只写“随便压一下看看”。
四、压测脚本设计
这个案例使用 JMeter 即可。
脚本结构可以很简单:
Thread Group
├ HTTP Header Manager
├ CSV Data Set Config
├ HTTP Request /api/order/detail
├ JSON Assertion
└ Aggregate Report
需要准备的数据:
- 用户 token
- 订单 id
为什么不用固定一个订单号?
因为固定数据可能导致:
- 缓存命中过高
- 数据库执行路径失真
- 压测结果偏乐观
五、压测过程
一个合理的加压过程通常不是一步打满,而是逐步增加。
例如:
| 并发数 | 目标 QPS | 持续时间 |
|---|---|---|
| 50 | 200 | 5 分钟 |
| 100 | 400 | 5 分钟 |
| 200 | 800 | 10 分钟 |
| 300 | 1100 | 10 分钟 |
这样做的好处是:
- 能看出性能拐点
- 能减少一次性打挂系统的风险
- 更容易定位在哪一档开始恶化
六、压测结果示例
假设结果如下:
| 档位 | QPS | 平均 RT | P95 | 错误率 |
|---|---|---|---|---|
| 200 QPS | 205 | 55ms | 90ms | 0 |
| 400 QPS | 398 | 88ms | 140ms | 0 |
| 800 QPS | 790 | 180ms | 260ms | 0.05% |
| 1100 QPS | 920 | 420ms | 900ms | 1.2% |
从结果看出:
- 800 QPS 基本接近目标
- P95 已经略超目标
- 继续加压后系统没有线性增长
- 1100 QPS 时明显进入瓶颈区
七、结合监控继续分析
压测结果只能说明现象,还要结合监控看原因。
假设监控显示:
- 应用 CPU 只有 55%
- JVM 没有明显 Full GC
- 数据库连接数很高
- 慢 SQL 数量明显增加
这时一个合理判断是:
接口瓶颈大概率在数据库,而不在 Java 应用本身。
继续排查 SQL,发现一个明细查询语句没有走索引:
select * from order_item where order_no = ?
如果 order_no 没有索引,随着并发升高,RT 很容易抖起来。
八、可以给出的优化建议
针对这个案例,可以提出几类优化:
1. 数据库优化
- 给订单明细表补索引
- 避免
select * - 减少重复查询
2. 应用优化
- 聚合查询结果,减少重复调用
- 对热点订单详情增加缓存
- 优化线程池参数
3. 架构优化
- 查询读写分离
- 接口结果缓存
- 异步化非关键步骤
九、这个案例说明了什么
这个案例非常典型,说明了三个事实:
1. 单接口压测也要准备真实数据
否则结果不可信。
2. 性能问题不一定是 Java 代码本身
很多时候是数据库、缓存、网络等依赖问题。
3. 达标不只看平均值
业务方往往更关心:
- P95 是否稳定
- 错误率是否可接受
十、适合零基础读者的实践建议
如果你刚开始学压测,可以先按这个顺序练手:
- 选一个查询接口
- 准备一批真实参数
- 用 JMeter 做阶梯加压
- 记录 QPS、P95、错误率
- 同时观察数据库和 JVM 指标
不要一开始就上复杂的全链路压测。
先把一个接口压明白,收获会更大。
十一、总结
接口压测案例的重点不在于把数字压到多高,而在于形成一套完整思路:
- 明确目标
- 准备真实数据
- 合理加压
- 分析结果
- 结合监控定位瓶颈
- 给出优化建议
这套方法,后面做系统压测和业务流程压测时同样适用。