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 指标之间的关系:一张图说清楚

下面这张图,是我自己总结的「性能指标关系图」。每次做优化前,我都会先过一遍这张图,确认自己没漏掉什么。

性能指标关系图 系统性能 响应时间 吞吐量 资源利用率 可用性 P50 / P99 / Avg QPS / TPS CPU / Mem / IO 错误率 / SLA 优化原则 先定指标,再定目标。优化一个指标时,必须观察其他三个指标的变化。

2.7 如何选择正确的指标?

指标不是越多越好。选错了指标,优化方向就偏了。

我一般按这个步骤来:

  1. 先看业务场景:是读多写少,还是写多读少?是实时交互,还是离线批处理?
  2. 再定核心指标:用户侧看响应时间,系统侧看吞吐量,成本侧看资源利用率。
  3. 最后定目标值:比如「P99 响应时间 < 200ms」「单机 QPS > 5000」。

一个小技巧:目标值不要拍脑袋定。先跑一周线上数据,看看当前的水平,再定一个「跳一跳够得着」的目标。

2.8 避坑指南

最后,分享几个我踩过的坑:

  • 只看平均值:平均值会掩盖长尾问题。一定要看百分位分布。
  • 忽略资源利用率:响应时间和吞吐量都达标了,但 CPU 已经 95% 了。一有流量波动,系统就崩。
  • 指标太多,没有重点:同时优化 10 个指标,等于一个都没优化。每次只盯 1-2 个核心指标。
  • 测试环境和线上环境指标不一致:线上 TP99 是 100ms,压测环境只有 20ms。别高兴太早,先看看压测环境是不是配了 10 倍的机器。

我曾经犯过的错:有一次优化数据库查询,把 TP99 从 2s 降到了 200ms,特别开心。结果上线后,数据库 CPU 从 30% 飙到了 90%。因为我把一个慢查询优化成了快查询,但查询次数翻了 10 倍。总资源消耗反而更大了。从那以后,我每次优化都会同时看「响应时间」和「资源利用率」两个维度。

好了,这一章的内容就到这里。记住一句话:没有度量,就没有优化;选对指标,优化就成功了一半。