压测场景
压测最有价值的部分,不是把并发压上去,而是学会根据曲线和监控现象判断系统到底卡在了哪一层。
核心结论
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 为什么会“先升后降”
这是一个很典型的容量模型问题:
- 压测初期,并发增加,线程池还有空闲线程,所以吞吐继续提升。
- 单请求变重后,线程占用时间变长,单位时间内能处理完的请求数下降。
- 当活跃线程数接近上限,请求开始排队,或者直接被拒绝。
- 被拒绝和超时的请求增多后,成功率下降,有效吞吐也随之下降。
- 部分线程完成后又能接收新请求,所以曲线可能不是断崖式下跌,而是波动后进入低成功率稳定区。
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 不高,但活跃线程很多。
六、压测时建议按什么顺序看问题
一个更高效的排查顺序是:
- 先看 QPS、RT、成功率三条主曲线。
- 再看应用 CPU、内存、GC、线程池、连接池。
- 然后看数据库、缓存、RPC、消息等下游指标。
- 最后结合
Arthas trace、日志、线程 dump、慢 SQL 做定位。
这样能避免一开始就钻进代码细节,却忽略了真实瓶颈在外部依赖。
七、总结
压测场景分析,核心不是记住某一种曲线,而是学会把“现象”和“资源约束”对应起来:
QPS 上不去,优先找流量入口和容量上限。QPS 先升后降,优先怀疑系统进入过载区。RT 变高但不报错,优先排查排队和等待。成功率低,优先确认是拒绝、超时、限流还是业务失败。
如果把这些场景和线程池、连接池、下游依赖、缓存命中率一起看,压测结论会比单看一个 TPS 数字有价值得多。