LabHub
学习 学习路径 课程

调试实战

把「慢」这个词换成数字

在 LabHub 中继续学习

一句话总结

只说“很慢”无法修复任何问题。把它改写成什么功能、从何时开始、慢多少、影响百分之多少,调查范围立刻会缩小到原来的十分之一。

概念图: 什么功能、从何时开始、慢多少、影响百分之多少 · 一直很慢和偶尔很慢的原因不同。 · 服务器思考的时间 · 每 20 人中就有 1 人要等待 3 秒。

为什么需要它

问题报告通常是这样提交的:“最近系统很慢。”

这时立即登录服务器查看 CPU,是最常见的错误。CPU 为 30% 时,人们会以“看起来正常”结束调查;CPU 为 90% 时,又会错误地以“就是 CPU 导致的”结束调查。两种结论都不是答案。

首先应该询问四个问题。

问题 为什么要问 答案能够缩小的范围
哪个页面或功能? 很少出现全部功能都慢 代码路径
从何时开始? 与部署、配置变更对照 原因发生的时间点
慢多少?(过去 2 秒,现在 20 秒) 区分慢 10 倍还是慢 10% 问题性质
总是发生,还是偶尔发生? 区分平均问题与尾部问题 调查方法

第四个问题尤其重要。**一直很慢和偶尔很慢的原因不同。**一直很慢通常来自结构问题(查询、N+1、同步调用);偶尔很慢通常来自竞争(锁、连接池、GC、磁盘)。把两类问题混在一起观察,只会被平均值掩盖,什么都看不出来。

拆分各个区段

把一个请求经过的路径分段,并测量每个区段的耗时。

클라이언트 → [네트워크] → 웹서버 → [앱] → [DB] → 앱 → 웹서버 → 클라이언트

即使没有专用测量工具,也可以只用一个 curl 拆分区段。

curl -o /dev/null -s -w \
 'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' \
 https://example.com/slow-page

仅凭这五个数字,就能区分“网络问题还是服务器问题”。大多数争论到这里就会结束。

不要相信平均值

平均响应时间为 200ms 的服务,仍然经常会收到“很慢”的投诉。如果 1,000 个请求中,950 个耗时 50ms,另有 50 个耗时 3 秒,平均值是 197ms。平均值正常,但每 20 人中就有 1 人要等待 3 秒。

因此,应查看百分位数。

指标 含义 用途
p50(中位数) 一半请求比它更快 典型体验
p95 每 20 人中 1 人经历的值 用户开始明显不满的位置
p99 每 100 人中 1 人经历的值 尾部问题,包括竞争、GC、重试
max 最差的单次请求 追踪异常值

如果 p50 不变,只有 p99 上升,问题不是容量,而是竞争。如果从 p50 开始一起上升,则是结构或容量问题。

负载与延迟是不同维度

CPU 使用率 60% 并不代表“还剩 40% 余量”。在排队论中,利用率升高时,等待时间不是线性增长,而是会急剧上升。超过 70% 后,只需再增加少量负载,延迟就可能增长数倍。因此,“CPU 明明还有余量”无法反驳延迟问题。

生产现场中的表现

缩小范围后应该测量什么

通过分段已经确认问题在服务器端后,下一步要查看的是服务器内部究竟在等待什么。常见错误是只根据 CPU 使用率判断;正如前一课程所述,服务器的大部分等待时间并不是在等待 CPU 调度。

应按顺序排除四类问题。

**第一,执行等待。**检查已经准备运行的任务是否多于 CPU 核数。如果负载平均值很高而 CPU 使用率很低,原因就不在这里。在容器中还要同时检查前面介绍过的节流。这是平均使用率不高、尾部延迟却突然升高的典型原因。

**第二,输入输出等待。**即等待磁盘或网络。数据库变慢通常也属于这里,此时应修复的不是应用程序,而是查询或索引。

**第三,锁与等待队列。**包括连接池、线程池、应用程序锁和数据库行锁。如果只有并发请求增加时才变慢,几乎总是这类问题;其特点是单独测试时无法复现。

**第四,外部调用。**即我们调用的其他服务变慢。此时我们能修改的只有超时、重试和降级,因此根因与应对措施彼此分离。

区分这四类问题成本最低的方法,是改变负载进行比较。只发送一个请求时也很慢,说明是结构问题(第一类或第二类);只有同时发送多个请求时才变慢,则说明存在竞争(第三类)。仅这一次比较,就能把调查范围缩小一半。

此外,**修复后必须用相同方法重新测量。**相信已经修好,与数字实际发生变化是两回事;如果最初没有测量值,也就没有依据声称问题已经改善。

后续实验要做什么

你将拿到一份包含 340 条真实请求的日志,并亲自回答前面的四个问题。所有答案都在数据中;只要按顺序缩小范围,一句“很慢”就会变成一份能够指向具体版本的报告。