2. 性能度量:如何定义性能?
做性能优化,第一件事不是动手改代码。
而是先搞清楚一件事:什么叫「快」?
你想想看,如果连目标都没定义清楚,你怎么知道优化做完了?我见过太多团队,上来就调参数、改架构,忙活一个月,一问性能提升了多少,答不上来。这就是典型的「没有度量,就没有优化」。
这一章,咱们就把性能度量这件事彻底聊透。
2.1 性能度量的四个维度
我个人习惯把性能指标分成四个维度。每个维度回答一个核心问题:
| 维度 | 核心问题 | 典型指标 |
|---|---|---|
| 速度 | 用户等多久? | 响应时间、延迟、TP99 |
| 容量 | 系统能扛多少? | 吞吐量、QPS、TPS |
| 资源 | 花了多少成本? | CPU利用率、内存占用、IO |
| 可用性 | 系统稳不稳? | 错误率、成功率、SLA |
这四个维度缺一不可。只看速度不看容量,压测一上来就崩;只看资源不看速度,省了机器丢了用户。
核心原则:性能度量必须同时覆盖「用户体验」和「系统成本」。单看一个指标,很容易被误导。
2.2 响应时间:用户感知的「快」
响应时间,说白了就是用户发出请求到收到响应的时间差。
但这里有个坑:一次请求的响应时间不是固定的。它是个分布。
我在项目中遇到过这种情况:平均响应时间 50ms,看起来不错吧?但实际有 5% 的请求超过 2 秒。用户投诉的就是那 5%。
所以,我们通常看这几个值:
- 平均响应时间:容易算,但容易被极端值带偏。
- 中位数(P50):一半请求比它快,一半比它慢。比较稳定。
- TP99(P99):99% 的请求比它快。这才是真正的「用户体验底线」。
- 最大值:看看最差情况有多差,但别拿它当优化目标。
我的习惯:线上监控重点看 P99,压测时看 P50 和 P99 的差距。差距越大,说明系统抖动越严重。
2.3 TP99:为什么它是黄金指标?
TP99,全称是「第 99 百分位响应时间」。
什么意思?举个例子:你收集了 1000 个请求的响应时间,按从小到大排序。第 990 个值就是 TP99。也就是说,99% 的请求都比这个值快。
为什么我特别看重 TP99?
- 平均响应时间会骗人:一个 10 秒的超时请求,能把平均值从 100ms 拉到 200ms。但 TP99 几乎不受影响。
- TP99 反映长尾:系统 99% 的情况都稳定,那 1% 的慢请求才是用户流失的元凶。
- 优化 TP99 就是优化稳定性:把 TP99 降下来,整个系统的抖动就小了。
我曾经踩过的坑:只盯着平均响应时间优化,把平均值从 200ms 降到了 50ms。结果上线后用户投诉变多了。一查才发现,TP99 从 500ms 涨到了 2s。因为我把缓存全堆在内存里,GC 一触发,整批请求都卡住了。平均值好看了,用户体验反而更差了。
2.4 吞吐量与 QPS:系统能扛多少?
吞吐量,是单位时间内系统能处理的请求数量。
最常见的两个指标:
- QPS(Queries Per Second):每秒查询数。常用于读场景,比如搜索、列表页。
- TPS(Transactions Per Second):每秒事务数。常用于写场景,比如下单、支付。
吞吐量和响应时间是什么关系?
很多人以为它们是独立的。其实不然。
当系统负载低的时候,响应时间基本不变。但负载一上去,响应时间会急剧上升。这个拐点,就是系统的最大吞吐量。
关键认知:优化吞吐量,本质上是在「不显著增加响应时间」的前提下,让系统处理更多请求。
2.5 资源利用率:花了多少成本?
性能优化不是无限堆机器。你得知道资源用在哪了。
| 资源 | 关注点 | 常见瓶颈 |
|---|---|---|
| CPU | 计算密集型还是等待密集型? | 高 CPU 通常意味着代码效率低 |
| 内存 | 堆使用、GC 频率、缓存命中率 | 内存泄漏、频繁 Full GC |
| 磁盘 IO | 读写延迟、IOPS、吞吐量 | 日志写太多、数据库刷盘慢 |
| 网络 | 带宽、连接数、丢包率 | 连接池不够、序列化开销大 |
我一般会先看资源利用率,再决定优化方向。CPU 跑满了,你优化数据库查询没用;磁盘 IO 打满了,你加内存缓存才是正解。
2.6 指标之间的关系:一张图说清楚
下面这张图,是我自己总结的「性能指标关系图」。每次做优化前,我都会先过一遍这张图,确认自己没漏掉什么。
2.7 如何选择正确的指标?
指标不是越多越好。选错了指标,优化方向就偏了。
我一般按这个步骤来:
- 先看业务场景:是读多写少,还是写多读少?是实时交互,还是离线批处理?
- 再定核心指标:用户侧看响应时间,系统侧看吞吐量,成本侧看资源利用率。
- 最后定目标值:比如「P99 响应时间 < 200ms」「单机 QPS > 5000」。
一个小技巧:目标值不要拍脑袋定。先跑一周线上数据,看看当前的水平,再定一个「跳一跳够得着」的目标。
2.8 避坑指南
最后,分享几个我踩过的坑:
- 只看平均值:平均值会掩盖长尾问题。一定要看百分位分布。
- 忽略资源利用率:响应时间和吞吐量都达标了,但 CPU 已经 95% 了。一有流量波动,系统就崩。
- 指标太多,没有重点:同时优化 10 个指标,等于一个都没优化。每次只盯 1-2 个核心指标。
- 测试环境和线上环境指标不一致:线上 TP99 是 100ms,压测环境只有 20ms。别高兴太早,先看看压测环境是不是配了 10 倍的机器。
我曾经犯过的错:有一次优化数据库查询,把 TP99 从 2s 降到了 200ms,特别开心。结果上线后,数据库 CPU 从 30% 飙到了 90%。因为我把一个慢查询优化成了快查询,但查询次数翻了 10 倍。总资源消耗反而更大了。从那以后,我每次优化都会同时看「响应时间」和「资源利用率」两个维度。
好了,这一章的内容就到这里。记住一句话:没有度量,就没有优化;选对指标,优化就成功了一半。