云计算百科
云计算领域专业知识百科平台

性能测试问题排查思路

1、先排掉"假问题"(30% 的坑在这)

很多所谓"性能上不去",其实是压测本身的问题。这一步不先做,后面全白干。

检查点

怎么看

典型症状

压测机自身瓶颈

top、CPU、内存、网络

压测机 CPU 打满 → TPS 是压测机的上限,不是服务端的

端口耗尽

ss -s、netstat

TIME_WAIT 暴涨,Cannot assign requested address

网络带宽

iftop、sar -n DEV

带宽跑满,RT 全线拉长

脚本问题

看请求是否真发出去

think time 设错、断言太重、CSV 读取慢

连接池/客户端限制

JMeter 的 httpclient 连接数

并发设了 500,实际连接数只有 20

判据黄金口诀:

TPS 上不去,但服务端资源(CPU/内存/IO)都很闲 → 大概率是压测端或链路阻塞,不是服务端性能问题。


2、建立"三要素"关联视图

任何性能问题,都要同时看这三个指标的关系,缺一不可:

TPS(吞吐量) ↔ RT(响应时间) ↔ 资源利用率(CPU/内存/IO/网络)

核心定律:

  • CPU 涨,TPS 涨​ → 正常,还没到瓶颈
  • CPU 涨,TPS 不涨,RT 涨​ → 快到瓶颈了,开始排队
  • CPU 不涨,TPS 不涨,RT 涨​ → 有阻塞(锁、IO 等待、外部依赖、连接池不够)
  • CPU 涨,TPS 反降​ → 线程上下文切换严重,或 GC 频繁

第二和第三种是最常见的两类问题,后面分开讲。


3、分层定位漏斗(从外到内)

按这个顺序往下钻,每层都有明确的"证据"决定是否下钻:

① 网络/负载均衡 → ② 应用服务器 → ③ JVM → ④ 中间件/外部依赖 → ⑤ 数据库 → ⑥ 代码

① 网络 & 负载均衡

  • 看:带宽、丢包率、LB 连接数、DNS 解析
  • 工具:iftop、sar -n DEV、ping、mtr
  • 典型问题:带宽打满、SLB 连接数限制、跨可用区调用

② 应用服务器(系统层)

  • 看:CPU、内存、磁盘 IO、上下文切换、打开文件数
  • 工具:top、vmstat、iostat、pidstat、dstat
  • 关键指标:
    • us(用户态CPU)高​ → 业务代码在算,往下钻代码
    • sy(内核态CPU)高​ → 系统调用频繁(大量 IO/网络/锁竞争)
    • wa(IO等待)高​ → 磁盘或外部 IO 慢
    • cs(上下文切换)暴涨​ → 线程数过多,在疯狂切换

③ JVM 层

  • 看:GC 频率/耗时、堆内存、线程状态
  • 工具:jstat -gcutil、jmap、jstack、Arthas dashboard
  • 典型问题:
    • Full GC 频繁​ → 内存泄漏或堆太小 → jmap dump + MAT 分析
    • Young GC 耗时高​ → 对象创建过快,看 jstat 各区回收情况
    • 大量线程 BLOCKED​ → 锁竞争 → jstack 或 Arthas thread -b

④ 中间件 / 外部依赖

  • 看:Redis、MQ、第三方接口、连接池
  • 典型问题:
    • 连接池打满(Druid/HikariCP 等待数)→ 慢 SQL 拖住连接
    • Redis 大 key、热 key、连接池不够
    • 第三方接口 RT 长 → 串行调用放大 RT

⑤ 数据库(最常见的终极瓶颈)

  • 看:慢 SQL、锁等待、连接数、Buffer Pool 命中率
  • 工具:慢查询日志、show processlist、explain、Arthas trace 定位到 SQL
  • 典型问题:
    • 没走索引、索引失效
    • 大表 JOIN、深分页
    • 行锁/表锁等待
    • 连接数打满

⑥ 代码层

  • 到这一层就是最后一步了,靠 Arthas / APM / profile 火焰图
  • 典型问题:循环里查数据库、同步锁范围过大、序列化开销、日志打太多

4、两大经典场景的排查路径

场景 A:CPU 高、TPS 上不去

top → 找到 CPU 高的进程
top -Hp <pid> → 找到 CPU 高的线程
printf %x <tid> → 转 16 进制
jstack <pid> | grep -A20 <hex> → 看这个线程在干嘛

或者 Arthas 一步到位:

thread -n 3

往下判断:

  • 栈在业务方法​ → 算法/循环问题,用 profiler 火焰图找热点方法
  • 栈在 GC 线程​ → 内存问题,转 JVM 排查
  • 栈在序列化/JSON​ → 数据量太大或序列化框架慢

场景 B:CPU 不高、但 RT 很长、TPS 上不去 ← 面试最爱考

这是阻塞型问题,排查思路完全不同:

1. jstack / Arthas thread 看线程状态
→ 大量 WAITING/BLOCKED
2. 看在等什么:
– 等数据库连接池 → 连接数不够 或 慢 SQL 占着连接
– 等 Redis/HTTP 连接 → 外部依赖慢
– 等 synchronized 锁 → 锁竞争激烈(thread -b 直接找)
– 等线程池队列 → 线程池核心数/队列配置不合理
3. Arthas trace 看方法内部耗时分布
→ 定位到底卡在哪一跳

关键洞察:

CPU 低 + RT 高 = 系统在"等",不是在"算"。要找"等什么",不是找"算什么"。


五、一个实战排查模板(可直接套)

# === 第 0 步:确认压测端没问题 ===
# 压测机 CPU/网络是否正常

# === 第 1 步:系统层 ===
top # 看整体负载、CPU 分布
vmstat 1 # 看 cs(上下文切换)、wa(IO等待)
pidstat -u -p <pid> 1 # 进程级 CPU

# === 第 2 步:JVM 层 ===
jstat -gcutil <pid> 1000 # 看 GC 频率和耗时
jstack <pid> > /tmp/stack.txt # 抓线程栈(多抓几次)

# === 第 3 步: Arthas 精准定位 ===
dashboard # 整体面板
thread -n 3 # CPU Top3
thread -b # 找死锁/阻塞源
trace <class> <method> '#cost>200' # 只看耗时>200ms 的调用
watch <class> <method> '{params, returnObj}' -x 2

# === 第 4 步:数据库 ===
# 开慢查询日志 / show processlist / explain

线程栈抓下来后,重点看大多数线程停在哪一个栈帧——那个就是瓶颈。


六、排查心法(比工具更重要)

  • 先测量,再优化:没有数据支撑的优化都是玄学
  • 一次只改一个变量:改完重测,才能确定效果
  • 从大到小,从粗到细:先确定是哪一层(网络/应用/DB),再深入具体方法
  • 看趋势,不看快照:性能问题要看压测过程中的曲线变化(内存是否持续增长?TPS 是否随时间下降?)
  • TPS 下降比 RT 变长更早暴露问题:RT 是结果,TPS 和资源的关系变化才是预警信号

  • 七、记忆锚点

    一看压测端,二看三要素(TPS/RT/资源),三分层下钻,四分 CPU 高还是等阻塞。

    CPU 高往下找"算什么",CPU 低往下找"等什么"。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 性能测试问题排查思路
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!