把「很慢」这条报障拆开
目标
将“服务器很慢”拆分成CPU、内存、I/O 中的具体一项。亲自读取 数字,并通过趋势斜率区分泄漏与缓存。
为什么重要
收到性能缓慢报告后,最常见的应对是“升级配置”。但如果一台机器上有 20 个 D 状态 进程,导致 load 为 20,那么增加 CPU 不会产生任何效果。 找到连接症状与原因的数字,就是本实验的全部内容。
此环境的限制本身就是训练
此 Pod 已移除全部内核权限,因此无法使用 perf、strace、bpftrace。
我们改为直接读取 /proc 和 /sys/fs/cgroup。这些正是上述工具
在内部所做的事情,也是在无法安装工具的客户服务器上实际需要完成的
工作。
步骤
- 60 秒分类 →
/root/perf/01-triage.txt - 两次读取
/proc/stat计算 CPU 使用率 →/root/perf/02-cpu.txt - CPU 占用最高的进程 →
/root/perf/03-top.txt - RSS、PSS、Private_Dirty →
/root/perf/04-mem.txt - 制造泄漏并通过斜率确认 →
/root/perf/05-slope.txt - cgroup 限制 →
/root/perf/06-cgroup.txt - 区分 anon 与 file →
/root/perf/07-split.txt - 三行结论 →
/root/perf/08-verdict.md
参考
top中的 %CPU 即使超过 100 也属正常——因为它以单个核心为基准。free中应该查看的值不是free,而是available。- 汇总多个进程的内存时,应使用 PSS 而不是 RSS。
60 秒分类
60 秒分类 → /root/perf/01-triage.txt
在 /root/perf/01-triage.txt 中写入四行:loadavg 的三个数字 / 按状态统计的进程数量(R、D、S)/ 核心数 / available 内存。使用的命令是 cat /proc/loadavg、ps -eo state --no-headers | sort | uniq -c、nproc、free -m。本步骤用于确定接下来查看什么。
手动计算 CPU 使用率
两次读取 /proc/stat 计算 CPU 使用率 → /root/perf/02-cpu.txt
以 1 秒间隔读取两次 /proc/stat 中的 cpu 行,计算使用率,并只将数字写入 /root/perf/02-cpu.txt(0~100)。busy=user+nice+system+irq+softirq+steal,idle=idle+iowait。这就是 top 所做的计算。
找出谁在使用 CPU
CPU 占用最高的进程 → /root/perf/03-top.txt
使用 ps -eo pid,pcpu,comm --sort=-pcpu | head,将排名第一的进程名称作为一行写入 /root/perf/03-top.txt。如果没有负载,可以先执行 python3 -c 'while True: pass' & 制造一个再观察。
区分 RSS、PSS、Private_Dirty
RSS、PSS、Private_Dirty → /root/perf/04-mem.txt
任选一个进程,将 grep -E '^(Rss|Pss|Private_Dirty):' /proc/<PID>/smaps_rollup 的结果原样保存到 /root/perf/04-mem.txt。必须包含全部三行。
制造泄漏并通过斜率捕获
制造泄漏并通过斜率确认 → /root/perf/05-slope.txt
运行一个故意泄漏的程序。例如 python3 -c "import time;L=[];\nwhile True: L.append(bytearray(1024*1024)); time.sleep(0.2)" &。以 5 秒间隔读取该 PID 的 Private_Dirty 四次,并逐行保存到 /root/perf/05-slope.txt。值必须单调增加。
查看容器的真实限制
cgroup 限制 → /root/perf/06-cgroup.txt
在 /root/perf/06-cgroup.txt 中写入 memory.max、memory.current、cpu.max 三个值。cgroup v2 位于 /sys/fs/cgroup/ 之下。关键在于这些数字与主机的 free 不同。
是堆还是缓存
区分 anon 与 file → /root/perf/07-split.txt
将 grep -E '^(anon|file) ' /sys/fs/cgroup/memory.stat 保存到 /root/perf/07-split.txt。即使 memory.current 达到上限,如果大部分是 file,说明它是可回收缓存;如果是 anon,则是真正的内存压力。
用三行写出结论
三行结论 → /root/perf/08-verdict.md
在 /root/perf/08-verdict.md 中写入三行:(1)症状来自 CPU、内存还是 I/O;(2)作为判断依据的数字;(3)下一步要检查什么。没有数字的结论只是猜测。