03.10 系统诊断:从 IM 消息时延到资源证据链
返回第三卷 · 进程前置:03.03 · CPU 前置:03.04 · 内存前置:03.05 · I/O 前置:03.09 · 业务测量前置:11.01
03.10 系统诊断:从 IM 消息时延到资源证据链
DeepTutor 初稿经技术与教学审阅后的静态课程。下面的进程编号、主机、连接数和所有指标均为虚构纸上样本;没有运行
ps、/proc、vmstat、iostat、ss、Go、IM 服务、基准或站点。本章只讨论只读观测的含义、作用域与证据强度,不给任何真实环境下的故障结论。
一、“消息慢”先变成可检查的业务症状
假设虚构 c-a 的历史查询在同一接口、同一请求大小和近似每秒 100 次请求的两个连续 5 分钟窗口中,P95 从 60 ms 升到 240 ms。这条描述比“网关变慢”具体:说明了哪个用户可见操作、哪两个窗口、样本量级与分位数口径。11.01–11.02 已讲业务确认点和分布;这里用给定的合成 P95 当输入,不声称由真实请求计算得出。
先写至少四个可反驳的候选:处理任务在等 CPU;页面/内存压力拖慢了工作;本机或下游存储变慢;慢接收方和 socket 队列拖住处理。还可能是锁、网络、权限查询或远端数据库。一个指标变化只是线索,不能从“历史慢”直接选中一项原因。
| 第一遍 | 第二遍 | 交付物 |
|---|---|---|
| 症状、作用域、时间窗、进程/内存/CPU 字段 | 块 I/O、socket、竞争假设与下一项观测 | 两窗口合成表、假设矩阵和一页证据报告 |
本章用 Brendan Gregg 的 USE 视角整理“资源使用、排队/饱和、错误”三类问题,作为检查顺序,而非自动诊断算法。S4 先学只读观察与推理;03.11 的容器配额、11 卷的负载和剖析会补齐更深的运行证据。
二、先定范围:指标属于谁、哪一刻、哪一种单位
纸上设网关进程运行在主机 h-a 的容器 ct-a 中,某观察时 PID 为 4102;这些名称全是虚构。ps 和 /proc/<pid>/status 看进程,vmstat 常看当前系统的进程/内存与 CPU 视角,iostat 看设备,ss 看socket;它们不是自动按 c-a 历史查询筛选的业务指标。容器内看到的 PID、设备与宿主机视角还可能不同,后续 03.11 继续。
| 先记录 | 为什么必须记录 |
|---|---|
| 事件窗口与采样时刻 | 不同时间的快照不能拼成同一次故障 |
| 主机/容器/进程身份 | PID 可复用,同一数值可能指向下一次进程实例 |
| 单位与分母 | ms、字节、百分比、每秒速率及 P95 属于不同量 |
| 采样方法与权限 | 首行累计、瞬时快照、间隔平均和看不到的对象会影响解释 |
| 业务路径 | 本机磁盘指标未必对应远端数据库查询 |
只读入口也要克制:检查必要的 PID、状态、RSS、FD 数量和 socket 汇总即可;不要把环境变量、令牌、真实用户地址、聊天路径或完整 /proc/<pid>/environ 复制进课程记录。03.03 已说明 /proc 并非全部路径只读;本章只讨论明确的观测字段。
三、CPU 与等待:ps/vmstat 不能被一列数字代表
ps 的 PID/STAT 是一次进程快照。Linux 的 R 可表示正在运行或可运行,S 多是可中断等待;只看一个字母不能断定某条 IM 请求究竟在等锁、网络还是存储。vmstat 的 r 是可运行任务数,b 是等待 I/O 完成的阻塞任务数;us/sy/id/wa 为系统 CPU 时间比例,wa 是 CPU 时间分类中的 I/O 等待视角。它们与某个请求的毫秒数没有一对一换算式。
vmstat 第一份活动统计常覆盖开机以来,后续按间隔报告;进程/内存列本身是当时快照。若要对齐事故窗口,应使用有明确间隔的多份样本,不能把开机以来的首行平均当作故障五分钟。si/so 表示交换换入/换出速率;零值说明该观测窗未见这类活动,不证明所有内存风险不存在。CPU 总体不满也不排除单核心热点、锁争用或被容器配额限制;这一步只能缩小假设范围。
| 字段 | 本章可说 | 不可直接说 |
|---|---|---|
r | 某时刻可运行任务的数量 | 某条消息一定在排 CPU |
b | 某时刻等 I/O 的任务数量 | 一定是数据库查询在等本地盘 |
wa | 系统 CPU 时间中的 I/O 等待份额 | 单个设备 await 或接口时延 |
si/so | 当前采样窗的交换活动 | 进程 RSS 或对象泄漏量 |
如果 r 升高且用户态 CPU 时间也变高,可把 CPU 排队作为候选;若 b/wa 同时升高,可优先检查 I/O,但两者仍需和业务请求路径对照。只因为 wa 高就宣称“磁盘坏了”,跳过了设备与远端依赖的证据。
四、进程内存与 FD:RSS 增长不等于 Go 堆泄漏
Linux /proc/<pid>/status 可看到 VmSize(虚拟范围)与 VmRSS(驻留集),后者还有匿名、文件映射和共享内存等分类;快速统计存在精度限制。若纸上 VmRSS 从 200 MiB 变为 220 MiB,只能说这个进程在两个采样时刻的驻留统计增加 20 MiB。03.05–03.06 已解释 Go 堆对象、页复用/归还、文件映射、栈和内核资源范围不同;一次差值不能证明泄漏,更不能直接解释 180 ms 的 P95 增量。
下一层要看同时间窗的连接数、缓冲上限、Go HeapAlloc/HeapReleased、RssAnon/RssFile 和 GC/交换线索。若 HeapAlloc 持续涨而流量和存活连接稳定,应检查哪些对象还被引用;若它下降而 RSS 仍高,先考虑分配器保留、文件映射或其他内存来源。/proc/<pid>/fd 的数量可帮助发现 FD 增长,但 2000 条连接自然可对应许多 FD;要比较基线、容量与错误,不能只凭“数值大”就判泄漏。路径和远端地址可能敏感,课程记录只保留必要的类型与汇总。
磁盘空间下降而目录里看不到大日志,也可回看 03.07 的“已删除但仍打开文件”;RSS 增长与 df 变化则是两类问题,不能混到一个“内存不足”标签下。
五、块设备:iostat await 是设备请求均值,不是业务 P95
iostat 的扩展设备报告里,await 是发到该设备的 I/O 请求从排队到完成的平均毫秒数,aqu-sz 是平均队列长度。它们的分母是设备请求,与 c-a 历史 HTTP 查询的 P95 分母不同。iostat 第一份报告默认覆盖开机以来,使用跳过首份报告的选项或读取后续间隔样本,才能与事故窗对齐。
%util 表示该设备有请求活动的时间比例;对串行处理设备接近 100% 可能提示饱和,对并行 RAID/现代 SSD 却不能单靠 100% 判定性能已到上限,官方手册明确提醒这一限制。要同时看 await、队列、吞吐、错误和设备能力,不能把 %util 当成一把通用红线。
更要先确定业务确实使用哪个设备。S3 教学数据库可能在远端,历史查询若走远端 SQL 或 MongoDB,本机 h-a 的磁盘 await 即使上升,也可能与请求慢无因果关系;日志写入或别的进程也能影响本机盘。下一项证据应是请求 Trace、数据访问阶段计时或数据库所在主机的设备/查询指标,而不是直接更换网关磁盘。
六、socket:连接数与队列不能替代在线、投递和业务积压
ss 可给 socket 状态与队列视图,ss -s 是汇总入口。纸上同一主机的 ESTABLISHED 计数近似 2000,仅说明该范围内有这些 TCP 连接状态;它不等于 2000 个业务在线用户,一个用户可有多设备,一条连接也可能尚未完成认证。若观察某些连接的发送/接收队列,也只能表明套接字层的数据状态,不能直接读作 Go 应用的有限输出队列、完整帧数或设备已展示消息。
03.09 已示范:本机可写不等于接收方已处理,fd11 可读不等于消息已拼好。04.06 又区分慢接收方与路径拥塞。因此若怀疑慢设备,至少把同一连接范围的 socket 队列、应用待发队列、发送失败/超时和设备确认点放在同一时间线。一个抽样 socket 的队列接近零,只能说明这个样本没有显示积压,不能排除别的连接或瞬时峰值。
ss 原始输出可能包含真实 IP、端口和进程信息。课程练习只保留汇总数量、队列单位与虚构标识,避免把生产网络拓扑或用户地址写入教材。若权限不足只能看到一部分连接,报告要注明观测范围。
七、同一张合成表里,有哪些竞争解释?
下面全是纸上合成输入:h-a/ct-a/PID 4102,两个相邻 5 分钟窗口,历史查询负载约 100 rps;系统列是各窗口多次间隔采样的代表值,不是计算出的精确总体分位数。ss 队列是少量连接抽样,设备是本机虚构 d0,和业务数据库设备的关系未知。
| 视角与单位 | 基线窗口 | 异常窗口 | 可说与不能说 |
|---|---|---|---|
| 历史查询 P95,ms | 60 | 240 | 业务时延升高 180 ms;原因未知 |
vmstat r,任务数 | 2 | 2 | 未见可运行数随之升高;不能排除单核/配额/锁 |
vmstat b,任务数 | 0 | 4 | 有更多任务在等 I/O;不知属于谁 |
vmstat wa,CPU 时间 % | 2 | 22 | I/O 等待份额上升;非单请求时延 |
vmstat si/so,KiB/s | 0/0 | 0/0 | 样本中无交换速率;不证明无内存压力 |
iostat d0 await,ms/设备请求 | 4 | 38 | 本机 d0 请求均值升高;业务是否走 d0 待核对 |
iostat d0 aqu-sz,请求数 | 0.5 | 3 | 该设备排队增加;不等于查询排队 |
进程 VmRSS,MiB | 200 | 220 | 驻留多 20 MiB;不足以判泄漏 |
主机 ss ESTABLISHED,连接数 | 2000 | 2000 | 连接数约稳定;不等于用户在线数 |
| 抽样 socket 发送队列,B | 近 0 | 近 0 | 抽样未见明显积压;不能代表全部连接 |
| 应用/设备错误,次/窗口 | 未记录 | 未记录 | 缺失证据,不能把未采集填成 0 |
“本机块 I/O 变慢参与了历史查询时延”是一个优先核对的假设:b/wa 与 d0 await/aqu-sz 同涨提供线索。但若请求主要等远端数据库,这些本机数据可能只是同时发生的日志活动。CPU 瓶颈、内存压力与慢接收方也没有被这张表严格排除;每个候选都需要能反驳它的下一项证据。
| 候选 | 当前支持 | 当前反例/缺口 | 下一项更有区分力的证据 |
|---|---|---|---|
| 本机块 I/O | b/wa/await/aqu-sz 同窗上升 | 不知历史查询是否读取 d0 | 请求 Trace 的存储阶段、实际文件/设备映射 |
| CPU/锁 | P95 上升 | r 未上升,但总体数遮蔽单核与锁 | 同窗 CPU 与阻塞分解、后续 profile/trace |
| 内存压力 | RSS 上升 20 MiB | si/so 为零且无对象证据 | Go 堆、映射与容器内存限制时间线 |
| 慢接收方 | IM 有长连接 | 抽样发送队列近零,样本太小 | 应用有界队列、全量分布和设备确认日志 |
若端到端 Trace 显示额外 180 ms 主要在远端数据库等待,应转查远端请求/设备/锁的证据;若主要在本地排队,则重新评价 CPU、队列或文件 I/O。先定位耗时段,再在该段的资源作用域里找原因,比看到一个高值就调参更可靠。
八、交付一页可复核诊断报告与分层练习
学习者交付:写出业务症状与样本窗;标注每个字段的单位、主机/进程/设备/socket 作用域和首行/快照/间隔语义;为至少两种假设列支持、反例与下一只读观察;最后写出哪些数据因权限或脱敏而没有拿到。纸上表格只能练推理,不能代替真实故障现场证据或性能结论。
分层练习:先答,再展开反馈
1. “消息慢”缺少哪三个关键信息?
至少要明确操作/确认点、时间窗和时延或错误的量化口径。
2. 这次合成业务指标是哪一个?
c-a 历史查询的 5 分钟窗口 P95,60 ms→240 ms。
3. P95 增加了多少毫秒?
180 ms;这是两个给定合成数的差,不是设备 await。
4. USE 的三类检查是什么?
资源使用、饱和/排队和错误;它是组织问题的检查表。
5. PID 4102 可当作永久进程身份吗?
不能。PID 会复用,还要记录时间、主机/容器和进程实例。
6. `ps` 的 R 能证明正在占用一个 CPU 吗?
不能。R 可包含正在运行或可运行等待 CPU。
7. `vmstat r` 与 `b` 各代表什么?
r 是可运行任务数;b 是等待 I/O 完成的阻塞任务数。
8. `vmstat wa=22%` 是历史请求时延 22% 吗?
不是。它是系统 CPU 时间的 I/O 等待分类份额。
9. `vmstat` 第一行活动统计能直接代表事故五分钟吗?
不能。通常覆盖开机以来;要读与事故窗对齐的间隔样本。
10. `si/so=0` 能证明没有任何内存问题吗?
不能。只说明本观测窗未见交换速率,仍需看对象、限制和其他指标。
11. `VmRSS` 从 200 到 220 MiB 能证明 Go 堆泄漏吗?
不能。RSS 含多类驻留页,要对照 Go 堆、映射、连接与时间窗。
12. `iostat await=38 ms` 与 HTTP P95=240 ms 分母一样吗?
不一样。前者是该设备 I/O 请求均值,后者是业务请求分位数。
13. `aqu-sz=3` 表示三条 IM 消息排队吗?
不是。它是设备 I/O 请求的平均队列长度。
14. 并行 SSD 的 `%util` 接近 100% 就可直接断言饱和吗?
不能。该值对并行设备不直接反映性能上限,需结合延迟、队列、吞吐和设备能力。
15. 本机 d0 `await` 上升就证明远端数据库慢吗?
不能。先核对请求实际数据路径、远端主机与耗时段。
16. `ss` 的 ESTABLISHED 数等于在线用户数吗?
不等于。一个用户可有多设备,连接状态与业务认证/在线状态不同。
17. 一个 socket 发送队列近零能排除所有慢设备吗?
不能。样本太窄,也看不到应用有界队列与瞬时峰值。
18. 本案例先检查本机 I/O 的理由是什么?
同窗 b/wa 和 d0 await/aqu-sz 上升使它成为候选,但还缺业务路径证据。
19. 下一项能区分本机盘与远端等待的证据是什么?
请求 Trace/数据访问阶段计时,并核对实际存储设备和远端服务指标。
20. 可以把真实 IP、令牌和完整环境变量粘进练习报告吗?
不应。只记录必要汇总,脱敏并注明看不到的范围。
21. CPU 总体不满能排除单核热点和容器配额吗?
不能。系统平均值会遮蔽局部约束,03.11 再深化容器限制。
22. 这张合成表能证明唯一根因吗?
不能。它只帮助排列候选和选择下一项有区分力的证据。
来源与下一步
- Brendan Gregg:USE Method:按资源使用、饱和与错误组织性能调查,不替代根因验证。
- Linux
ps(1)、/proc/<pid>/status与vmstat(8):进程、内存、可运行/阻塞、交换和 CPU 时间字段。 - Linux
iostat(1)与ss(8):设备请求均值/队列与 socket 观察范围。
按学习路线,S4 主线下一章05.04 Go 内存模型解释并发可见性;S6 再回访03.11 隔离与限制和 03.12 资源故障案例。离开本章前,应能把业务症状、资源指标、作用域、竞争假设和下一项证据写在同一张纸上,而不从单个高值直接宣布根因。