真实面经题目 · 原创解析

怎么排查性能问题?

排查性能问题不能从单点经验出发,而要先把问题定义清楚:慢在哪里、影响谁、从什么时候开始、哪个指标异常、是否可复现。标准思路是先量化现象,再按调用链从客户端、网关、应用、缓存、数据库、网络和机器资源逐层缩小范围,结合压测、监控、日志、链路追踪、慢查询、线程栈、GC 日志、火焰图以及 CPU、内存、IO、网络等指标定位根因,最后通过修复验证和回归压测证明问题真正解决。

出现于:阿里巴巴 · 测开

60 秒回答模板

可以先定义性能问题的现象和指标,而不是直接去看某一类日志。比如确认是接口响应变慢、吞吐下降、超时增多、错误率上升,还是机器负载升高;同时记录 QPS、平均 RT、P95、P99、错误率、CPU、内存、GC、磁盘 IO、网络带宽、数据库连接数、缓存命中率等核心指标。第二步确认影响范围和时间线:是全站慢、单接口慢、单机慢、某个机房慢,还是某个版本上线后变慢。第三步沿请求链路拆分,从前端、DNS、CDN、网关、应用服务、缓存、数据库、第三方依赖、网络和机器资源逐层定位,用链路追踪看每段耗时,用监控看资源瓶颈,用日志看异常和超时,用压测复现瓶颈。第四步针对不同瓶颈采用不同工具:数据库看慢查询、执行计划、索引、锁等待和连接池;应用看线程栈、锁竞争、线程池、连接池、GC、火焰图;机器看 CPU、内存、磁盘 IO、网络、上下文切换;缓存看命中率、热点 key、大 key、穿透、击穿和雪崩。最后修复后要做对比验证:同等压测模型下比较修复前后的 QPS、P95、P99、错误率和资源使用率,并补充回归测试、容量评估和监控告警,避免只解决表面现象。

考点 先定义性能现象和核心指标
主线 按请求链路逐层缩小范围
易错点 一上来只说看日志,没有定义 QPS、响应时间、P95、…

深入解析

01

先定义性能现象和核心指标

排查性能问题的第一步是把慢转成可度量的指标。要确认慢的是页面加载、接口响应、批处理任务、消息消费、数据库查询,还是整体吞吐能力。常用指标包括 QPS、TPS、平均响应时间、P90、P95、P99、最大响应时间、错误率、超时率、并发数、队列长度、CPU 使用率、内存使用率、GC 次数和耗时、磁盘 IO、网络吞吐、数据库连接池使用率、缓存命中率等。只说用户反馈慢没有排查价值,必须明确影响范围、发生时间、触发条件、是否持续、是否与发布、流量增长、配置变更、数据量增长有关。性能排查本质上是从现象到指标,再从指标到瓶颈资源,最后从瓶颈资源到代码或架构根因。

02

按请求链路逐层缩小范围

性能问题通常不是孤立发生的,需要按请求经过的路径逐层拆解。一个典型请求可能经过浏览器或客户端、DNS、CDN、负载均衡、网关、应用服务、RPC 调用、缓存、数据库、消息队列和第三方服务。排查时要先判断慢在入口前还是入口后:如果服务端监控显示响应正常但用户侧慢,可能是前端资源、DNS、CDN、网络质量或客户端渲染问题;如果网关到应用耗时高,要继续拆分是应用内部处理慢、下游调用慢、数据库慢、缓存慢,还是线程池排队。链路追踪是关键工具,可以把一次请求拆成多个 span,看到每一段耗时、错误、重试和下游依赖,从而避免凭感觉怀疑某个模块。

03

用压测和对照实验复现问题

线上性能问题要尽量通过受控压测复现,否则容易被偶发流量、缓存状态和环境差异误导。压测前要明确模型:并发数、QPS、请求比例、数据规模、账号分布、热点数据、读写比例、持续时间和阶梯升压策略。压测中观察吞吐和响应时间曲线,如果 QPS 上不去且 RT 急剧升高,说明系统进入瓶颈区;如果错误率上升,可能是超时、连接池耗尽、限流、线程池拒绝或下游不可用。测试开发视角下还要做对照实验,比如单接口压测、去掉缓存压测、mock 下游压测、单机压测、数据库只读压测,通过控制变量判断瓶颈在应用、数据库、缓存还是外部依赖。

04

应用层定位

如果链路显示耗时集中在应用服务,就要进一步分析应用内部资源。首先看线程池是否耗尽、请求是否排队、连接池是否满、是否出现大量阻塞线程。可以抓取线程栈,观察线程停在数据库调用、远程调用、锁等待、文件 IO、序列化、正则匹配还是业务循环中。CPU 高时用火焰图或 profiler 分析热点函数,区分是业务计算、序列化反序列化、日志打印、加解密、压缩、对象创建还是锁竞争。内存异常时看堆内存、对象分布、Full GC 次数和停顿时间,判断是否有内存泄漏、大对象、缓存无界增长或频繁创建短生命周期对象。应用层排查不能只看异常日志,因为很多性能瓶颈不会报错,只表现为排队、阻塞、GC 或 CPU 消耗。

05

数据库层定位

数据库是性能问题高发点,但不能只看到慢查询就结束。要先确认数据库整体负载,包括 QPS、慢查询数量、CPU、IO、连接数、锁等待、主从延迟、事务耗时和 buffer 命中率。对慢 SQL 要分析执行计划,看是否走索引、是否全表扫描、是否 filesort、是否临时表、是否回表过多、是否分页 offset 过大、是否 join 顺序不合理。还要关注数据量变化和索引选择性,低选择性索引或函数包裹字段都可能导致索引失效。写入慢时重点看锁冲突、长事务、批量写、唯一索引冲突和磁盘刷盘。连接池打满时,表面现象可能是接口慢,但根因可能是 SQL 慢、事务未释放、连接泄漏或连接池配置不合理。

06

缓存层定位

缓存并不一定总能提升性能,缓存设计不当也会成为瓶颈。排查时要看缓存命中率、平均耗时、连接数、慢命令、大 key、热 key、内存淘汰、网络流量和集群节点负载。如果命中率突然下降,可能是缓存失效策略、key 规则变化、批量过期、数据预热不足或缓存穿透。热点 key 会导致单节点压力过高,即使整体缓存集群看似正常,局部节点也可能成为瓶颈。大 key 会造成网络传输和序列化耗时过高,也可能引发阻塞。还要判断是否存在缓存击穿、缓存雪崩、缓存与数据库不一致导致的重复回源,以及缓存超时时间设置过于集中等问题。

07

机器和网络层定位

当应用和数据库指标不能解释问题时,要回到基础资源。CPU 高需要区分用户态 CPU、系统态 CPU、负载均值和上下文切换,用户态高通常指向计算热点,系统态高可能与 IO、网络、锁或内核调用有关。内存高要看是否接近 OOM、是否频繁换页、是否容器内存限制过小。磁盘 IO 高要看读写吞吐、IOPS、await、util 和日志写入压力,数据库、日志系统和本地文件操作都可能触发磁盘瓶颈。网络问题要看带宽、丢包、重传、连接数、TIME_WAIT、DNS 耗时和跨机房调用延迟。机器资源排查要结合容器限制和调度情况,因为宿主机争抢、限流和资源配额也会造成应用侧响应变慢。

08

修复后必须验证和回归

性能问题修复不能只凭一次访问变快就结束,必须建立修复前后的对比。验证时要保持相同压测模型、相同数据规模和相同环境条件,对比 QPS、P95、P99、错误率、CPU、内存、GC、数据库负载、缓存命中率和下游调用耗时。还要补充回归测试,确认功能正确性没有被优化破坏,比如索引新增是否影响写入,缓存策略调整是否造成脏数据,异步化是否影响一致性,批处理优化是否改变边界结果。最后要沉淀监控和告警,把本次暴露出的关键指标纳入观测体系,并做容量评估,明确当前架构在多少 QPS、多少数据量、多少并发下会再次触顶。

易错点

  • 一上来只说看日志,没有定义 QPS、响应时间、P95、P99、错误率等指标。
  • 只怀疑数据库,不按前端、网关、应用、缓存、数据库、网络和机器资源完整拆链路。
  • 压测模型过于简单,只打单接口,不考虑真实流量比例、数据分布、缓存状态和持续时间。
  • 把平均响应时间当成唯一指标,忽略 P99、超时率、错误率和长尾延迟。
  • 找到慢查询后直接加索引,不分析执行计划、数据分布、锁等待和写入影响。
  • 修复后没有做同条件对比压测,也没有补充回归验证和监控告警。
  • 只关注代码逻辑,不检查线程池、连接池、GC、CPU、内存、磁盘 IO 和网络重传。

面试官追问

如果一个接口 P99 很高,但平均响应时间正常,应该怎么排查?

P99 高说明少量请求非常慢,通常要关注长尾问题。先按链路追踪筛选慢请求,比较它们和正常请求的差异,比如请求参数、数据量、命中的数据库分片、缓存是否命中、是否发生重试、是否等待锁、是否触发 Full GC、是否被线程池排队。平均值正常不能说明系统健康,因为用户体验往往被长尾延迟影响。

CPU 使用率很高时,如何判断是代码问题还是系统资源问题?

先区分用户态 CPU 和系统态 CPU。用户态 CPU 高通常需要用火焰图或 profiler 找热点方法,常见原因是复杂计算、循环、序列化、加密压缩、正则或对象创建过多。系统态 CPU 高则要关注上下文切换、网络 IO、磁盘 IO、锁竞争和内核调用。还要结合线程数、负载均值、GC、容器限额判断是否是资源配额不足。

数据库慢查询已经找到后,下一步怎么分析?

不能只看到慢 SQL 就直接加索引。要看执行计划、扫描行数、过滤比例、是否走索引、是否回表、是否排序、是否临时表、join 顺序是否合理,再结合业务访问频率和数据分布决定优化方式。可能的修复包括改索引、改 SQL、减少返回字段、分页优化、拆分查询、读写分离、缓存热点结果或调整事务范围。

如何判断性能问题是不是缓存导致的?

看缓存命中率、请求耗时、慢命令、大 key、热 key、连接数、内存淘汰和回源数据库的流量变化。如果缓存命中率下降且数据库压力同步上升,可能是穿透、击穿或雪崩。如果缓存节点局部负载高,可能是热点 key。如果单次缓存读取很慢,可能是大 key、网络传输或序列化成本过高。

测试开发在性能排查中应该承担什么角色?

测试开发不仅是执行压测,还要设计可解释的性能实验。需要搭建监控指标、构造贴近真实业务的压测模型、控制变量复现问题、输出瓶颈证据、验证优化效果,并把性能场景纳入回归体系。好的性能测试结论应能回答瓶颈在哪里、为什么发生、修复是否有效、系统容量边界是多少。