3. 性能指标与目标:QPS、延迟、吞吐量的定义与衡量方法

聊到性能优化,第一个绕不开的话题就是——你到底要优化什么?

我见过不少团队,上来就撸袖子改代码,压测一通乱跑,结果改了半天连基础指标都没对齐。今天就掰扯清楚三个最核心的指标:QPS、延迟、吞吐量。

3.1 三个指标,到底是什么?

先给个通俗说法:

  • QPS(Queries Per Second)——每秒能处理多少个请求。说白了就是系统的瞬时抗压能力。
  • 延迟(Latency)——一个请求从发起到收到完整响应,花了多少毫秒。用户体感最直接的指标。
  • 吞吐量(Throughput)——单位时间内系统成功处理的总数据量。比如每秒处理了多少字节的审计日志。

嗯,光看定义好像没啥难的。但实际项目中,这三个指标常常互相拉扯。我上次调一个审计日志写入接口,把QPS提上去了,结果延迟从30ms飙到了200ms……用户直接投诉超时。你想想看,提高QPS不一定就是好事,得看业务容忍的延迟阈值。

我的习惯:先定延迟上限,再压QPS,最后算吞吐量。这三个顺序别搞反。

3.2 怎么衡量它们?

3.2.1 QPS 的测量方法

最常见的工具就是压测工具,比如 wrk、JMeter、Locust。我习惯用一个简单脚本跑固定并发,持续30秒,看平均每秒成功请求数。

# 用 wrk 压一下审计接口
wrk -t4 -c100 -d30s http://audit-api:8080/collect
# 输出中的 Requests/sec 就是 QPS

但注意:别只看平均值。峰值QPS、中位数QPS、尾延迟期间的QPS,都得看。我曾经遇到一个接口,前25秒都很稳,最后5秒突然掉到一半——原来GC在那时候疯狂触发。

3.2.2 延迟的衡量方法

延迟通常看分位值,别盯着平均值。平均值会被长尾请求拉偏。我一般关注三个点:

  • P50 —— 一半请求比这个快,一半比这个慢。日常体验基准。
  • P99 —— 99%的请求都在这个延迟内。核心优化目标。
  • P999(或P99.9) —— 最差的那千分之一请求。往往是GC、锁竞争、网络抖动的结果。

举个例子:

分位值 实际ms 含义
P50 25 一半请求在25ms内完成
P90 45 90%请求在45ms内
P99 80 99%请求在80ms内
P999 350 最差千分之一要350ms

你看看这个P999,350ms,跟P50差了十几倍。这样的接口在压测时平均延迟可能只有40ms,但一旦线上真实流量有毛刺,那千分之一的慢请求就会导致连接池占满、雪崩。所以我建议把P99延迟作为首要优化目标,而不是平均值。

我曾经踩过的坑:只压了200并发,平均延迟28ms,就高高兴兴上线了。结果双十一流量上来,P99直接飙到700ms,用户疯狂重试,把数据库打挂了。后来我每条接口都要求压到目标QPS的1.2倍,同时盯P99延迟不超过50ms。

3.2.3 吞吐量的衡量方法

吞吐量跟QPS关系密切,但不完全一样。QPS按请求数,吞吐量按数据量。审计接口尤其注意这一点——一个审计事件可能只有几百字节,也可能带附件达到几兆。

我一般这样算:

吞吐量(MB/s) = 平均请求大小(MB) × QPS

或者直接用工具测传输速率。比如用 iperf 测网络带宽上限,用 sar 看磁盘IO吞吐。

举个实际例子:审计日志聚合接口,每条日志平均1.2KB,QPS 5000,那吞吐量就是:

1.2 KB × 5000 = 6000 KB/s ≈ 5.86 MB/s

如果目标吞吐量是10MB/s,那就得优化带宽、压缩数据,或者提升QPS。三者是联动的。

3.3 三个指标之间的关系,一张图说清

我个人习惯把这三个指标画成一张三角关系图,每次优化之前都拿出来看看,防止偏废。下面这张SVG图就是我平时在知识库里存的那个版本:

性能指标三角关系 吞吐量 (Throughput) QPS 延迟 (Latency) QPS↑ → 延迟↑(资源争抢) QPS↑ → 吞吐量↑(线性关系) 延迟↓ → 吞吐量↑(释放资源)

你看图中箭头,QPS提高往往会带着延迟上升(红线),但延迟下降可以释放资源进而提升吞吐量(绿线)。优化的本质就是在这个三角里找到你业务能接受的平衡点。

3.4 怎么定性能目标?

我一般在项目启动前,跟业务方对齐一个标准表,比如这样:

场景 目标QPS P99延迟 吞吐量
审计日志写入 ≥8,000 ≤50ms ≥10 MB/s
审计日志查询 ≥2,000 ≤200ms ≥5 MB/s
审计报表导出 ≥100 ≤5,000ms ≥20 MB/s

你看,不同场景容忍度完全不同。写入要求低延迟,查询可以容忍稍高延迟但QPS不能低,报表导出是个重IO操作,QPS低但吞吐量要求高。没有一套目标打天下的说法。

一个好记的原则:先定延迟天花板,再反推QPS目标,最后验算吞吐量是否满足峰值带宽和磁盘IO。

3.5 实测中容易犯的几个错

  • 只测平均QPS,忽略波动:我建议压测至少要跑10分钟,观察最小、最大、标准差。如果波动超过15%,说明系统有瓶颈。
  • 忽略冷启动:刚启动的服务性能可能差2倍,等JIT预热完才稳定。我习惯先压2分钟“暖机”,再记录数据。
  • 把QPS和吞吐量混为一谈:曾经有人跟我说接口QPS到10万了,结果一看每条数据就几个字节,吞吐量才几MB。审计接口如果带大字段,吞吐量才是瓶颈。
  • 只看服务端,忽略网络和客户端:延迟可能发生在中间网络、DNS、负载均衡上。我遇到过客户端TCP参数没调,导致P99延迟多了30ms。

3.6 一个完整的衡量流程

  1. 确定业务容忍的延迟上限(例如P99 ≤ 100ms)。
  2. 用压测工具逐步加大并发,找到不突破该延迟上限的最大QPS。
  3. 在最大QPS下记录吞吐量,并对比带宽和磁盘IO是否达到极限。
  4. 留20%~30%余量给流量突刺,比如目标QPS是5000,压测至少要能扛6500。
  5. 部署到预发环境用真实流量回流验证——模拟环境永远有误差。
一个小技巧:我常用“目标倒推法”。比如业务说双十一峰值要扛2万QPS,那我会先把2万QPS下的P99压出来,如果超过100ms,就提前做拆分、缓存、异步化。别等到线上再补。