Linux 运维工程师面试题精选(二):性能分析与故障排查

如果说基础题考的是"知不知道",排障题考的就是"会不会查"。本组题目围绕 CPU、内存、磁盘、网络四条线展开,既有单指标的读法问题(load、iostat、free),也有组合题和开放题(网站突然变慢怎么查),答案里给的都是线上真实在用的工具链和判断顺序。

本文题目一览

  • 问题 1:load average 到底是什么意思,高了就一定是 CPU 不够吗
  • 问题 2:CPU 使用率的 us、sy、wa、st 分别代表什么,怎么定位
  • 问题 3:进程被莫名杀掉,怀疑 OOM killer 怎么确认
  • 问题 4:swap 到底要不要开,开多少合适
  • 问题 5:磁盘满了但 du 加起来没那么多,是怎么回事
  • 问题 6:文件已经 rm 删除,空间为什么没释放
  • 问题 7:iostat 的输出怎么看,%util 高就等于磁盘饱和吗
  • 问题 8:网络不通/丢包,你按什么顺序排查
  • 问题 9:服务器上大量 TIME_WAIT,是故障吗,怎么处理
  • 问题 10:too many open files 报错出现时怎么定位和处置
  • 问题 11:常调的内核参数有哪些,各自管什么
  • 问题 12:线上题——网站突然变慢,你的完整排查路径是什么

问题 1:load average 到底是什么意思,高了就一定是 CPU 不够吗

结论:load average 是单位时间内处于可运行(R)和不可中断睡眠(D)状态的任务平均数。它高只说明"排队等资源的任务多",等的可能是 CPU,也可能是磁盘 I/O——把 load 高直接等同于 CPU 不足是最常见的误判。

  • 判断基准要结合核数:8 核机器 load 长期在 8 上下是满载,冲到 20 是过载;单核机器 load 2 就已经排队了
  • 区分方向:load 高 + wa 高 → 等 I/O;load 高 + us/sy 高 → CPU 真忙;load 高但各项使用率都不高 → 怀疑大量 D 状态进程卡在某个 I/O 或锁上
  • 找 D 状态进程:ps aux | awk '$8 ~ /D/',再看它的内核栈 cat /proc/<PID>/stack
  • 三个数字是 1、5、15 分钟均值,看趋势方向比看绝对值更重要

问题 2:CPU 使用率的 us、sy、wa、st 分别代表什么,怎么定位

结论:us 是用户态计算,sy 是内核态开销,wa 是等 I/O 时的空闲,st 是虚拟化里被宿主机偷走的时间。先按构成定方向,再用进程级、线程级工具逐层收窄。

  • us 高:应用自身计算密集,top 找进程,perf top/火焰图找热点函数
  • sy 高:系统调用、软中断、上下文切换过多;vmstat 1 看 cs 列,perf record 看内核热点
  • wa 高:CPU 在等磁盘或网络存储,转去查 I/O,不要在 CPU 上纠结
  • st 长期大于 5%:虚拟机 CPU 账不可信,先找云厂商或宿主机层面确认超分问题
  • 工具链口诀:整机看 top/mpstat,进程看 pidstat,线程看 top -H,函数看 perf

问题 3:进程被莫名杀掉,怀疑 OOM killer 怎么确认

结论:OOM killer 是内核在内存(含 swap)耗尽时的自保机制,专挑"占用大、优先级低"的进程下手。确认方法很直接:看内核日志里的击杀记录,别靠猜。

  • 实锤证据:dmesg -T | grep -i "out of memory" 或 journal 里 "Killed process 进程名",会打印被杀进程的内存占用
  • 每个进程有 oom_score(内核评分)和 oom_score_adj(人工干预,-1000 表示豁免),关键进程可设负值降低被杀概率,但治标不治本
  • 分类处理:被杀的若是内存泄漏进程,修应用;若是正常进程被误杀,查是谁在吃内存——ps aux --sort=-%mem | head
  • 预防:给服务设 cgroup/systemd 的 MemoryMax,把 OOM 限制在自己的笼子里,别让单个服务拖垮整机随机杀人

问题 4:swap 到底要不要开,开多少合适

结论:建议开,但定位要摆正——swap 是内存压力的缓冲垫和冷页回收站,不是内存的替代品。真正要盯的不是"用了多少 swap",而是"还在不在持续换入换出"。

  • 判断标准看 vmstat 1 的 si/so:偶尔非零正常,持续大于 0 说明物理内存真不够,靠 swap 硬撑只会越来越慢
  • swappiness 控制内核使用 swap 的倾向:默认 60,数据库类可调到 1–10 减少无谓换出,但设 0 可能让内核宁可 OOM 也不换页,要谨慎
  • 容量经验:内存小于 16G 可按 0.5–1 倍配,大内存机器配 4–8G 做缓冲即可,没有放之四海的标准答案
  • 现代补充:zram/zswap 用压缩内存做交换区,是比磁盘 swap 更优的兜底方案,很多发行版已默认启用

问题 5:磁盘满了但 du 加起来没那么多,是怎么回事

结论:df 看的是文件系统块分配,du 看的是当前存在文件的大小总和,两者对不上时,差额通常来自两处:已删除但仍被进程占用的文件,以及预留块/稀疏文件等统计口径差异。先对差额找占用,别急着删文件。

  • 第一嫌疑就是"删了没释放":lsof +L1 列出链接数为 0 但仍打开的文件(下一题细讲)
  • 其他口径差异:ext 系默认给 root 预留 5% 块,df 的可用会更小;稀疏文件 du 看逻辑大小、df 看实际占用则相反
  • 别忘了还有一种满:inode 满,df -i 一起查才算完整
  • 定位大目录的稳妥姿势:du -x -h --max-depth=1 / 逐层往下,-x 避免跨到其他挂载点

问题 6:文件已经 rm 删除,空间为什么没释放

结论:因为文件还被进程打开着。Unix 的删除只是摘掉目录项(链接数减一),只要还有进程持有打开的文件描述符,数据块就不回收;进程关闭文件或退出后空间才真正释放。

  • 定位:lsof +L1 或 lsof | grep deleted,能看到进程名、PID 和文件大小
  • 处置:重启或 reload 持有进程即可释放;不想重启时,可通过 /proc/<PID>/fd/ 找到对应 fd 用 : > /proc/<PID>/fd/<fd号> 就地截断(仅对日志类文件安全)
  • 高发场景:应用还在写已轮转走的旧日志——logrotate 用了 copytruncate 之外的错误姿势或应用没收到重开信号
  • 规范做法:轮转后给应用发 reopen 信号(如 nginx 的 USR1),或让应用按大小自轮转,避免"删了个寂寞"

问题 7:iostat 的输出怎么看,%util 高就等于磁盘饱和吗

结论:不等于。%util 表示设备有 I/O 在处理的时间占比,现代 SSD 和多队列设备在 %util 100% 时吞吐还能继续涨。判断饱和要综合看 await(平均等待+处理时间)和队列长度(avgqu-sz)。

  • 核心指标:r/s、w/s 是 IOPS,rkB/s、wkB/s 是吞吐,await 明显高于设备正常延迟(机械盘约数毫秒、SSD 亚毫秒级)才是真排队
  • 工具姿势:iostat -x 1 看扩展指标,第一组是开机均值要丢弃,看后面每秒的增量
  • 分层定位:整机 I/O 高先用 iotop 或 pidstat -d 找到是哪个进程在读写
  • 追问方向:await 里包含排队时间,单看 svctm(老指标)会误判;块设备队列深度和调度器(mq-deadline/none)对云盘场景的影响

问题 8:网络不通/丢包,你按什么顺序排查

结论:按层排查,从本机往外推:先确认本机协议栈和配置,再看链路和对端,每一步都用计数器和抓包拿证据,而不是靠反复 ping 猜。

  • 本机层:ip a/ip route 看地址与路由,ss -s 看整体统计,防火墙规则别漏
  • 计数器层:ethtool -S 网卡 | grep -iE 'drop|err' 看网卡丢弃与错误增量,CRC 涨是物理层证据,先查线缆和光模块
  • 抓包层:双端 tcpdump 对比——发送端有、接收端无,丢在中间;接收端抓到但应用没收到,问题在本机协议栈以上
  • 常见背锅澄清:ping 丢包可能是对端限速 ICMP,不等于业务丢包,要用业务协议验证

问题 9:服务器上大量 TIME_WAIT,是故障吗,怎么处理

结论:多数情况下不是故障。TIME_WAIT 是主动关闭连接一方的正常收尾状态,作用是保证残留报文消散、最后 ACK 可重传,一般 60 秒自动消失。它只在数量大到耗尽本地端口时才是问题。

  • 先看量级:ss -s 或 ss -tan state time-wait | wc -l,几千个对服务器毫无压力
  • 真出问题的前提:作为客户端高频短连接打固定对端,端口(默认约 2.8 万个)被占满,新连接报 cannot assign requested address
  • 治本顺序:优先改连接用法(长连接/连接池)> 扩大 ip_local_port_range > 谨慎考虑 tcp_tw_reuse(仅客户端场景相对安全)
  • 明确禁区:tcp_tw_recycle 早被内核移除且在 NAT 环境下会丢连接,老博客里的"调优参数"不要照抄

问题 10:too many open files 报错出现时怎么定位和处置

结论:这是文件描述符耗尽,分为进程级(ulimit/服务 LimitNOFILE)和系统级(fs.file-max)两层。先确认是哪一层、哪个进程吃满,再谈改限制——无脑调大只是推迟泄漏进程的爆炸时间。

  • 看进程实际限制:cat /proc/<PID>/limits | grep "open files";看当前占用:ls /proc/<PID>/fd | wc -l
  • 看占用构成:lsof -p <PID> 按类型统计,socket 居多是连接没释放,普通文件居多是句柄没关
  • 系统级总量:cat /proc/sys/fs/file-nr,第一列是已分配数,对比 file-max 判断是否全局紧张
  • 处置分工:泄漏是应用 bug 要推修复;正常高并发则按压测数据抬 LimitNOFILE,并把验证步骤(改完重启服务再查 /proc)走完

问题 11:常调的内核参数有哪些,各自管什么

结论:调优的前提是先有瓶颈证据,参数按域来记:连接与队列、句柄、内存、conntrack 四类最高频。每个参数都要能说清"调大解决什么、调过头有什么副作用"。

参数 作用 注意
net.core.somaxconn 监听队列上限,还要同步改应用的 listen backlog 才生效 队列满会直接丢 SYN,日志里看 listen queue overflow 计数
fs.file-max / fs.nr_open 系统级与单进程级句柄天花板 要与服务的 LimitNOFILE 一起对齐
nf_conntrack_max 连接跟踪表大小,NAT/防火墙主机关键参数 表满会丢新连接,dmesg 有 "table full" 实锤日志
vm.swappiness 内存压力下使用 swap 的倾向 不是"越小越好",要看业务类型
net.ipv4.tcp_max_tw_buckets TIME_WAIT 数量上限 超限内核会主动销毁并打日志,属于止损不是优化

问题 12:线上题——网站突然变慢,你的完整排查路径是什么

结论:先定界、再分层。第一步不是登服务器,而是确认影响范围和起始时间:全站还是单个接口、所有用户还是某地区、慢在哪个时段开始——定界错了,后面全是无效劳动。

  • 先看变更:故障前一小时内有没有发布、配置变更、扩容、证书更换——大部分"突然变慢"都有对应的变更记录,先看它比先看指标快得多
  • 再看分层指标:入口流量与错误率 → 应用响应时间分位(P95/P99,不要看平均值)→ 依赖(数据库、缓存、消息队列)的延迟与连接数
  • 落到主机资源:CPU 看构成与 steal、内存看 available 与 si/so、磁盘看 await 与队列、网络看重传与丢弃计数,四条线各有工具链,前面几题就是干这个的
  • 抓现场再处置:重启能止损但会丢现场,先留 top/perf/线程栈/关键日志快照,再决定回滚、扩容还是重启
  • 收尾:恢复后补监控盲点、写复盘,把这次的定位路径固化成值班清单——面试时能讲出这一步的候选人,通常真值过班

面试官视角

这一组考的是排查的"顺序感"和对指标的理解深度。合格的回答有共同特征:先分清方向再拿工具(load 高先分 CPU 还是 I/O、df 和 du 对不上先想 deleted 文件),每个结论都有验证手段(看日志、看计数器增量、看 /proc 实际值)。明显的减分项是参数背诵式作答——上来就 tcp_tw_recycle、drop_caches、把 %util 当饱和度、把 TIME_WAIT 当故障——这些恰恰暴露了没在真实环境里处理过问题。真正的加分项在开放题里:先定界、先看变更、先留现场再止损,这套动作顺序比任何单个命令都值钱。

发表回复

后才能评论