性能指标与压测
性能优化从度量开始。面试主线:指标怎么定义、指标间什么关系、压测怎么做、瓶颈怎么找。
核心指标
| 指标 | 全称 | 含义 |
|---|---|---|
| QPS | Queries Per Second | 每秒查询数(读为主) |
| TPS | Transactions Per Second | 每秒事务数(写为主,含完整业务) |
| RT | Response Time | 单次请求响应时间 |
| 并发数 | 同时处理的请求数 | 与 QPS、RT 相关 |
RT 的统计口径:百分位
- 平均值会骗人:一个 10 秒的慢请求能把平均值拉高一倍,但 99% 的用户没感觉
- P99:99% 的请求快于这个值。看长尾,不看平均
- 常见口径:P50(中位数)、P95、P99、P999
- 面试话术:优化目标看 P99 而非平均值,平均值掩盖长尾问题
Little’s Law:三个指标的桥
并发数 = QPS × RT
QPS = 1000, RT = 200ms → 并发数 = 1000 × 0.2 = 200用途:
- 从压测指标推系统所需并发连接数
- 估算容量:目标 QPS 5000、RT 100ms → 需要 500 并发
- 反推瓶颈:并发数上不去,可能线程池/连接池打满
压测
工具选型:
| 工具 | 特点 | 场景 |
|---|---|---|
| wrk | 单机高并发,C 实现 | 快速压测 HTTP 接口 |
| k6 | 脚本化、云原生 | 持续集成压测 |
| JMeter | 功能全、学习成本高 | 复杂场景、分布式压测 |
| Locust | Python 脚本 | 业务脚本复杂时 |
方法论:
- 阶梯加压:从低并发逐步升高,找到吞吐拐点(QPS 不再增长甚至下降的点)
- 拐点之前是线性区,拐点之后是过载区(RT 飙升、错误率上升)
- 压测环境隔离:测试环境、测试数据,别压生产
- 记录完整指标:QPS、RT 百分位、错误率、CPU/内存/IO
- 结果对比基线,优化前后同条件对比
瓶颈定位
自上而下排查顺序:
瓶颈排查: 从入口逐层下探
- 先看最外层(LB、带宽),再看应用(CPU 高是计算密集,线程池满是阻塞)
- 缓存命中率低 → 查 key 设计和过期策略(见缓存设计篇)
- 数据库慢 SQL → EXPLAIN、索引(见数据库分类)
- 工具:APM 链路追踪看每层耗时占比,慢在哪一层一目了然
面试追问
- QPS 和 TPS 的区别? QPS 偏查询类,TPS 偏事务/写操作。实际面试常混用,说清口径即可
- 为什么看 P99 不看平均? 平均值被长尾拉高,掩盖大多数用户的实际体验。P99 反映最差 1% 的体验
- Little’s Law 怎么用? 并发数 = QPS × RT。估算容量、反推线程池大小
- 压测怎么找瓶颈? 阶梯加压找吞吐拐点。拐点处的资源(CPU/连接池/锁)就是瓶颈
- 平均 RT 正常但 P99 很高? 长尾问题:慢请求集中在个别节点(GC 停顿、冷缓存、锁竞争)。查 GC 和热点