Skip to content
发布于 更新于

压测场景 ​

压测最有价值的部分,不是把并发压上去,而是学会根据曲线和监控现象判断系统到底卡在了哪一层。

核心结论 ​

  • QPS 上不去,不一定是服务很强,也可能是压测机、网关、线程池或连接池先到瓶颈。
  • QPS 先升后降 往往意味着系统进入过载区,开始出现排队、拒绝、超时或失败重试。
  • 成功率低 不只是“慢”,更可能是线程池耗尽、下游限流、连接池打满后直接失败。
  • 判断压测问题时,必须把 QPS / RT / 成功率 / CPU / 线程池 / 连接池 / 下游错误 放在一起看。

一、QPS 上不去 ​

“QPS 上不去”是压测里最常见的现象之一,但原因通常不止一个。

1.1 压测机自身先到瓶颈 ​

典型现象:

  • 压测线程数继续增加,但目标系统监控变化不明显。
  • 压测机 CPU 很高,网卡带宽接近上限。
  • 压测工具本身出现连接、超时或发送能力不足。

判断方式:

  • 看压测机 CPU、内存、网络出口。
  • 看目标服务的请求量是否真的收到压测流量。
  • 多台压测机分摊流量再验证一次。

1.2 网关或入口层限流 ​

典型现象:

  • 服务本身资源不高,但请求量始终上不去。
  • 网关、Ingress、SLB、Nginx 层有大量限流、熔断、连接拒绝日志。
  • 应用侧 QPS 远低于压测侧发出的 QPS。

判断方式:

  • 看网关限流规则、并发连接数、超时设置。
  • 对比入口层与应用层的请求统计。

1.3 应用线程池先满 ​

典型现象:

  • CPU 不一定很高,但 RT 上升明显。
  • 活跃线程数持续逼近上限。
  • 出现线程池拒绝、EXHAUSTED、排队过长等日志。

判断方式:

  • 看业务线程池活跃线程数、队列长度、拒绝次数。
  • 看线程 dump 是否存在大量阻塞、等待下游返回的线程。

1.4 数据库或连接池瓶颈 ​

典型现象:

  • RT 主要消耗在 SQL 或下游持久层。
  • 数据库连接池活跃数打满。
  • 慢 SQL、锁等待、连接获取超时增多。

判断方式:

  • 看数据库连接池使用率。
  • 看 SQL RT、锁等待、慢查询日志。
  • 区分是数据库算不过来,还是应用拿不到连接。

二、QPS 先升后降,成功率下降 ​

这是一个非常典型的“系统进入过载区”场景。

2.1 现象描述 ​

常见曲线表现为:

  • 前期并发升高时,QPS 正常上涨。
  • 到某个拐点后,QPS 不再上涨,甚至开始下降。
  • 成功率同步下滑。
  • RT 往往上升,错误数明显增加。

2.2 商品标签查询案例 ​

在一个商品标签查询场景里,返回标签数量从 1 个增加到 50 个后,压测出现如下问题:

  • 业务线程处理单个请求的时间变长。
  • Dubbo 业务线程池逐渐打满。
  • 新请求被拒绝,出现 EXHAUSTED 错误。
  • QPS 先上升,随后下降并趋于一个较低水平。
  • 成功率显著降低,因为一部分请求直接失败而不是正常返回。

2.3 为什么会“先升后降” ​

这是一个很典型的容量模型问题:

  1. 压测初期,并发增加,线程池还有空闲线程,所以吞吐继续提升。
  2. 单请求变重后,线程占用时间变长,单位时间内能处理完的请求数下降。
  3. 当活跃线程数接近上限,请求开始排队,或者直接被拒绝。
  4. 被拒绝和超时的请求增多后,成功率下降,有效吞吐也随之下降。
  5. 部分线程完成后又能接收新请求,所以曲线可能不是断崖式下跌,而是波动后进入低成功率稳定区。

2.4 这个场景该看哪些指标 ​

观察项要看什么
业务线程池活跃线程数、队列长度、拒绝次数
Dubbo 线程池是否出现 EXHAUSTED、线程耗尽
RT平均值、P95、P99 是否同步上升
成功率是业务失败还是系统拒绝
CPU是否真的计算打满,还是线程只是在等待
下游服务是否是下游变慢导致线程被占住

2.5 这个场景的本质 ​

这个问题本质上不是“压测工具有问题”,也不一定是“机器性能差”,而是:

请求变重之后,原来的线程池容量和调用链路承载能力不再成立。

三、QPS 稳定,但 RT 越来越高 ​

这种场景也很常见,说明系统未必立刻失败,但已经开始排队。

典型现象:

  • QPS 没有明显下降。
  • 成功率短时间内看起来还可以。
  • RT 持续升高,尤其是 P95、P99。

常见原因:

  • 线程池排队。
  • 数据库连接池等待。
  • 下游接口变慢但未完全超时。
  • 锁竞争、串行化资源争用。

这类问题的危险点在于:

  • 早期看起来“服务还活着”。
  • 但只要流量再高一点,就可能从排队直接进入失败区。

四、成功率高,但抖动明显 ​

有些系统在压测时成功率很高,看起来没报错,但曲线并不健康:

  • RT 抖动明显。
  • P99 比平均值高很多。
  • 某些时间段突然出现尖刺。

常见原因:

  • 缓存命中率不稳定。
  • 周期性 GC。
  • 热点 Key、热点分片。
  • 慢 SQL 偶发出现。
  • 下游服务局部抖动。

这类场景容易被忽略,因为“没失败”。但如果线上叠加真实业务流量波动,就很容易放大成故障。

五、如何判断瓶颈在本服务还是下游 ​

压测排查里,一个非常重要的问题是:

到底是本服务自己扛不住,还是下游把本服务拖慢了?

可以从下面几个角度判断:

5.1 更像本服务瓶颈 ​

  • CPU 很高。
  • 本地线程池、连接池先满。
  • 代码热点集中在本地计算、锁、对象处理。
  • 下游 RT 正常,但本服务 RT 高。

5.2 更像下游瓶颈 ​

  • 本服务线程大多阻塞在 RPC、SQL、HTTP 调用上。
  • trace / profiler 里远程调用占比明显更高。
  • 下游错误率、超时率同步上升。
  • 本服务 CPU 不高,但活跃线程很多。

六、压测时建议按什么顺序看问题 ​

一个更高效的排查顺序是:

  1. 先看 QPS、RT、成功率三条主曲线。
  2. 再看应用 CPU、内存、GC、线程池、连接池。
  3. 然后看数据库、缓存、RPC、消息等下游指标。
  4. 最后结合 Arthas trace、日志、线程 dump、慢 SQL 做定位。

这样能避免一开始就钻进代码细节,却忽略了真实瓶颈在外部依赖。

七、总结 ​

压测场景分析,核心不是记住某一种曲线,而是学会把“现象”和“资源约束”对应起来:

  • QPS 上不去,优先找流量入口和容量上限。
  • QPS 先升后降,优先怀疑系统进入过载区。
  • RT 变高但不报错,优先排查排队和等待。
  • 成功率低,优先确认是拒绝、超时、限流还是业务失败。

如果把这些场景和线程池、连接池、下游依赖、缓存命中率一起看,压测结论会比单看一个 TPS 数字有价值得多。

基于 VitePress + GitHub Actions 自动部署