尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Linux故障排查实战手册:从磁盘告警到CPU飙高的系统化方法

发布时间:2026/9/13 13:28:36

资讯中心
01
ARTICLE

Linux故障排查实战手册:从磁盘告警到CPU飙高的系统化方法

Linux故障排查实战手册:从磁盘告警到CPU飙高的系统化方法
凌晨两点钉钉群里一条“磁盘告警”直接把睡意干没了。点开一看某台业务机器 / 使用率 96%再翻监控已经持续写了半小时日志。那一刻脑子里的第一反应不是“为什么”而是“先杀进程还是先腾空间”。这几乎是每个 Linux 运维都经历过的深夜场景告警不会挑工作时间来故障也不会按你的技能树出题。这份《Linux 故障排查实战手册》不是教科书式的命令罗列而是把我这些年处理线上故障的套路、踩过的坑、以及“到了现场先干什么后干什么”的节奏整理成一张能照着走的作战地图。目标是让新同学遇到告警不至于抓瞎让有经验的兄弟也能在复盘时对照查漏。无论你用的是 CentOS、Ubuntu 还是国产化系统这套方法论基本通用核心就是把“慌乱”变成“流程”。1. 故障排查的整体逻辑先定级再分层别上来就敲命令很多人一收到告警就冲上机器top敲完没看明白又去df -h紧接着tail -f刷日志半小时过去问题没定位现场反而被自己冲乱了。排查故障和急诊分诊是一个道理先稳住局面再按优先级处理最后才谈得上根治。1.1 第一步判断故障等级决定你的响应姿态先花十秒钟搞清楚三件事影响面多大是单机问题还是集群/多节点同时告警。同时告警优先查公共依赖数据库、网关、存储、网络出口。业务是否已受损用户能感知超时、报错、卡顿和暂时无感响应级别完全不同。是否在持续恶化比如磁盘以每分钟 2% 的速度在涨这比一个已经稳定在 95% 的磁盘要紧急得多因为留给你的窗口期可能只剩半小时。我自己的习惯是把告警分为 P1/P2/P3 三档。P1 是业务挂了或即将挂需要立即介入甚至回滚P2 是资源濒临临界值、性能明显劣化可以花 5-10 分钟盘一下再动手P3 是可疑苗头比如某进程内存缓慢上涨能等到白天再慢慢查。定级的作用是约束你的行为避免在 P1 场景下还去慢慢研究根因先止损再说。1.2 第二步按“硬件-系统-应用”三层快速切分定完级接下来就是分诊。我一直沿用“白盒三层法”硬件层CPU 是否飙满、内存是否耗尽、磁盘是否写满、网卡是否有错包。这些相对直观命令也就top/free/df/ip -s link那几条。系统层进程是否异常、文件句柄是否泄漏、系统负载为何升高、内核日志有没有报错。要看ps、/proc、dmesg以及/var/log/messages这类系统日志。应用层业务日志、慢查询、接口调用链、GC 情况。应用相关的排查往往最耗时因为它需要结合业务逻辑光看系统指标不够。三层不是孤立存在的。比如 CPU 飙高可能是应用死循环也可能是内核态频繁切换还可能是被邻居机器吵到了超线程/云上宿主干扰。我的建议是快速把三层的证据各收集一轮再判断重点深挖哪一层。切忌拿着锤子看什么都是钉子只会top的人容易把所有问题都归成“Java 线程问题”。1.3 第三步留好现场再动手这条是我踩坑换来的血泪教训。早些年处理一次 CPU 飙高我上去就把可疑进程 kill 了结果进程死了现场也没了连是什么业务逻辑导致的都没办法复盘。现在我的规矩是任何操作之前的 30 秒先把现场“快照”留全。# 保留故障时的关键信息防止因为误操作丢失现场 { echo time ; date echo load/top ; top -bn1 | head -30 echo mem ; free -h echo disk ; df -hT echo io ; iostat -x 1 3 echo net ; ss -antp | head -100 echo process ; ps -eo pid,ppid,%cpu,%mem,rss,cmd --sort-%cpu | head -40 echo dmesg ; dmesg -T | tail -100 } /tmp/troubleshoot_$(date %Y%m%d_%H%M%S).log 21这段脚本我建议直接存到服务器上随便找个目录放着比如/opt/scripts/snapshot.sh出现告警先跑一遍再开始排查。文件不大但能让你后续复盘时知道“当时到底发生了什么”而不是靠记忆脑补。2. 五类高频告警的快速定位路径说句实在话运维 80% 的告警都逃不出这五类CPU 飙高、内存不足、磁盘写满、网络异常、进程丢失。下面把每一类的快速定位路径和我的判断经验写清楚。2.1 CPU 飙高先分清是用户态、内核态还是上下文切换top显示 CPU 100% 时先按键盘数字1看每个核的情况再按P按 CPU 排序。但如果只看这一屏你很容易误判因为 CPU 高背后至少有四种完全不同的原因用户态高%us应用或脚本在拼命计算最常见是死循环、大循环、频繁 GC。内核态高%sy系统调用过于频繁常见于大量小文件读写、频繁创建和销毁线程、iptables 规则过多、网络软中断密集。软中断高%si网卡多队列不均、单队列网卡流量被打满。等待 IO 高%waCPU 在等磁盘表面看 CPU 高根子在磁盘慢。# 查看 CPU 核心数、负载和 top 进程 lscpu | grep -E ^CPU\(s\)|^Model name|^Socket|^Core|^Thread uptime # 按 CPU 排序看进程 top -bn1 | sort -k9 -rn | head -20 # 确认上下文切换和运行队列 vmstat 1 5如果vmstat里cscontext switch达到几十万甚至上百万说明系统在疯狂切换线程这时候与其盯top不如去数线程数。Java 应用线程数飙到几千光切换就能把 CPU 吃满。我处理过最典型的一个案子就是线程池没配拒绝策略请求积压后疯狂 new 线程最终 CPU 100%。2.2 内存不足OOM 只是结果内存去哪了才是问题看到free -h显示 available 很小别急着加内存。Linux 的 free 命令里 buff/cache 是会被回收的真正要警惕的是可用内存available持续走低。更直接的信号是dmesg里出现Out of memory: Killed process。内存排查路径我一般这样走# 看整体内存分布 free -h # 按内存占用排序进程第二行按物理内存排序 ps -eo pid,ppid,rss,vsz,cmd --sort-rss | head -20 # 观察 OOM 是否在内核日志里留下了痕迹 dmesg -T | grep -i -E out of memory|killed process # 统计各进程的页表、堆、栈等细分内存需要 root cat /proc/meminfo | grep -E MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree一个常被忽略的点是top里的 RES 并不等于进程真正占用的物理内存多个进程共享的共享库和共享内存会被重复计算。判断内存泄漏比较可靠的手段是持续观察几天看 RSS 是否符合业务周期。如果业务没增长、请求量没变RSS 却一直阶梯式上涨那基本就是泄漏。用jstat看 Java 堆、用pmap看进程地址空间也能进一步缩小范围。我踩过的一个典型坑某系统内存告警free显示 cached 占了 10G一堆同事说内存泄漏要重启。其实那只是内核用它来做 page cache业务高峰过后不一定需要释放真正到内存紧张时内核会优先回收缓存。别动不动就重启先把数据看明白。2.3 磁盘写满从“谁占的空间”和“谁在写”两头查磁盘告警往往是最让人头大的因为空间是慢慢没的而且“谁占空间”和“谁在写文件”经常不是同一个答案。比如日志文件虽然被删了但进程还持有句柄空间一直不释放——这是经典中的经典。# 查看磁盘和 inode 占用 df -hT df -iT # 找出超过 1G 的大目录以 / 为例按需修改路径 du -hx --max-depth2 / 2/dev/null | sort -rh | head -30 # 找出被删除但依旧被进程占用的文件空间不释放的元凶 lsof L1lsof L1这条命令值得单独说。正常情况下进程打开的文件会有链接计数删除后计数变 0。当你把日志文件rm了但没重启应用应用依旧往那个 fd 里写lsof L1就能列出那些“link count 1”的文件。解决办法要么 kill 进程要么 /proc/pid/fd/n清空那个句柄后者可以不用重启服务就释放空间是线上保命技能。2.4 网络异常连接数、丢包、端口一个都不能漏网络类告警通常表现为连接超时、连接数过多、丢包率上升、网卡软中断打满。我喜欢按“四查法”来走# 查看监听端口和连接状态统计 ss -antp | awk NR1 {print $1} | sort | uniq -c | sort -rn # 查看网卡收发包、错误、丢弃统计 ip -s link show eth0 # 查看 socket 队列是否堆积Recv-Q/Send-Q ss -lnt连接数异常高且大量集中在TIME_WAIT先看系统参数net.ipv4.ip_local_port_range和net.ipv4.tcp_tw_reuse的配置如果大量连接是SYN_RECV那要考虑是不是被扫了端口或回包有问题如果Recv-Q长期不降通常是应用读得慢不是网络问题。有一个经验值得记牢尽量不要在排查阶段把时间耗在ping上。ping通只代表 ICMP 通不代表 TCP 通了业务就通。线上很多故障是“ping 全通业务全挂”。要用telnet/curl测端口用ss看队列用tcpdump抓包才能把问题拉到正确的层面。2.5 进程异常白了、僵了、丢了三种情况三种打法进程常见异常有三位S 状态的 D不可中断睡眠、Z僵尸、以及进程一会儿有一会儿没有。D 状态基本是进程在做 IO卡在磁盘或 NFS 上ps -o stat里看到 D 就去查存储Z 状态说明子进程死了但父进程没调用 wait批量出现时盯父进程多半是父进程逻辑有 bug进程一会儿有一会儿没有优先看 supervisor/systemd 重启策略和业务崩溃日志。# 找出 D 状态和 Z 状态进程 ps -eo pid,ppid,stat,cmd | grep -E [DZ] # 查看 systemd 服务的重启次数和最近日志 systemctl status service-name systemctl show service-name | grep -E NRestarts|ExecMain在这里插一句遇到进程反复重启不要只盯着业务日志先看systemctl status开头的几行那里有最后一次退出的时间、退出码甚至main process exited, codekilled, status9这种关键信息能帮你快速判断是被 OOM kill 了还是被 systemd 超时杀掉了。3. 让排查事半功倍一套顺手的高频命令组合排查就是打仗兵器得趁手。下面这套组合拳我用了很多年覆盖面足够应对 90% 的 Linux 故障场景。每个命令都会给一句“什么场景下使用”的说明方便你按需取用。3.1 性能看板四件套top、vmstat、iostat、sartop -bn1非交互模式取一次快照适合写脚本也可以把结果落到日志里。vmstat 1 5观察运行队列、CPU 空闲、IO 等待、上下文切换5 秒采样 5 次。iostat -x 1 3看每块盘的%util、await、svctm。%util接近 100% 只说明盘忙不一定是容量问题可能是 IO 模式太差。sar -q -f /var/log/sa/sa$(date -d yesterday %d)回溯历史负载判断是偶发还是持续。很多问题你接手时已经过去了sar是帮你坐时间机器的工具。提示sar需要 sysstat 包支持部分精简系统可能没装提前确认好。如果没有历史数据也别慌/var/log/messages、应用日志里的时间戳也能帮你重建现场。3.2 日志检索三板斧grep、tail、journalctl日志是排查的“监控探头”不会用日志等于盲人摸象。# 看某个服务的实时日志 journalctl -u service-name -f journalctl -u service-name --since 10 minutes ago # 传统日志目录按关键字捞 grep -E ERROR|Exception|Timeout /var/log/app/xxx.log | tail -200 # 统计错误出现频次比看原始日志更能判断趋势 grep -c OutOfMemoryError /var/log/app/xxx.log grep -oE ERROR [^ ] /var/log/app/xxx.log | sort | uniq -c | sort -rn | head -20看日志的核心技巧不是“看全文”而是“先看类型和频次”。拿grep -oE提取异常的摘要信息再用uniq -c排序往往一眼就能看出是哪类错误最多。不要一上来就tail -f盯屏那是工作效率黑洞。3.3 现场快照脚本把上面整套组合成一条命令把常用命令合成一个脚本放到每台服务器的/opt/scripts/遇到告警直接跑输出文件再慢慢看。脚本不必复杂关键是每条命令都要能独立执行一个挂了不影响其他部分。之前给的snapshot.sh就是一个好模板使用前根据自己的环境删减命令即可。另一个实用技巧把snapshot.sh做成定时任务每小时跑一次保留最近 7 天。这样遇到故障时即使你没来得及采集现场因为定时快照已经帮你把“谱”记下来了。代价极小收益极大我强烈推荐。4. 三个真实案例复盘从告警到根因的完整闭环光说理论不够我把三个处理过的典型故障复盘出来每个案例都按“告警现象、排查过程、根因定位、解决措施”的顺序写展示实战中这套地图是怎么用的。4.1 CPU 飙到 200% 的“罪魁祸首”居然是日志框架现象某业务机 CPU 告警top看到 java 进程占了 200%双核但业务并发并不高。排查过程先用top -H -p pid看到两个线程 CPU 高拿到线程号转成十六进制jstack后找到了日志输出相关的类。此时我还没下结论又去看了磁盘 IOiostat显示那块盘的%util不高。最后翻应用配置发现日志级别是 DEBUG而且输出到一个终端文件每条日志都会执行同步 flush。根因日志框架在 DEBUG 级别下每条日志都会做一次序列化IO 操作CPU 消耗被日志写放大。不是业务逻辑问题是“打日志”本身把 CPU 吃掉了。解决日志级别调整为 INFO关闭控制台输出核心接口降级为异步日志。CPU 直接落回 5%。这个案例想说明什么CPU 高不代表应用在做业务计算很有可能是“辅助动作”在空转。排查时千万别只看业务代码日志框架、监控 agent、备份脚本统统可能是元凶。4.2 磁盘 100% 又释放不了的“灵异事件”现象监控告警/使用率 100%但du -sh /*一层层看下去加起来远远小于df显示的总占用。排查过程我先跑了df -hT看到/dev/mapper/root满了然后lsof L1果然列出好几个被删除但仍被进程持有的文件全部是应用日志。原来应用日志通过 logrotate 按天切割但应用进程没收到信号重新打开文件老文件被删除后句柄一直指向那个 inode空间就没真正释放。根因不是“日志文件太多”而是“删除了文件但进程没释放 fd”。所以如果你只盯着目录看永远找不到是谁占了空间因为文件已经不在目录里了。解决lsof L1列出 pid 和 fd 号之后用ls -l /proc/pid/fd/确认然后用 /proc/pid/fd/fd号把那个句柄清空。这样不用重启应用磁盘空间立即释放。然后再回头修 logrotate 的配置加copytruncate或告诉应用重新打开日志。4.3 内存频繁 OOM最终揪出了隐藏的“缓存雪崩”现象某缓存服务内存告警频繁 OOM触发进程被内核杀掉重启后过几小时又 OOM。排查过程dmesg里能看到完整的 killed process 记录包括当时进程的 RSS 和 swap 使用。接着看free -hswap 使用了大量空间但我注意到一个反常的事缓存服务配置的 maxmemory 明明远低于物理内存。翻应用监控发现是在某个固定时间点后内存开始线性上涨而这个时间点正是某个“批量预热缓存”的任务执行时间。根因预热任务一次性往缓存写入千万级 key导致服务内部数据结构膨胀和频繁 rehash直接打爆了 maxmemory 限制。OOM 是结果罪魁是任务设计不合理没有做分批限速。解决把预热任务改成分批写入加限速同时监控缓存 key 数量变化曲线。此后内存曲线变得平稳。从这个案例能学到一个通用原则OOM 不可怕可怕的是 OOM 之前你不看历史曲线。任何内存问题都要回答“从什么时候开始涨的”这个问题而这个答案监控图比命令更能告诉你。5. 排查完之后的收尾别让告警第二天再来敲门故障恢复不是终点你要做的是让同类问题下次别再半夜把你叫醒。收尾阶段我固定做三件事写小结、补监控、改代码或配置。每一步都不复杂但漏掉一步下个夜班就在前面等你。5.1 补好监控和告警阈值很多故障并不是“突然发生”的只是你缺了发现它的眼睛。比如磁盘空间如果你只在 90% 才告警那留给你的处理窗口自然很窄如果你从 60%、70%、80% 分级告警就能提前发现“每周稳定增长 5%”的慢性问题。监控建议不用很贵很复杂最简单的方案是 crontab shell 脚本 企业微信机器人/钉钉机器人。脚本检查指标超过阈值调 webhook 发消息。效果立竿见影而且不依赖特定监控平台。关键是把阈值定得不扰民但留足窗口比如磁盘 80% 告警、90% 严重告警CPU 持续 10 分钟 90% 才告警避免瞬时尖峰误报。5.2 写好一份“20 分钟内能看懂的复盘记录”复盘记录的核心不是记录操作步骤而是记录“决策链路”你当时看到了什么证据、为什么判断是某一层的问题、最后怎么验证的。这比洋洋洒洒写几千字操作流水更有价值。我一般用四段式现象监控图/告警消息截图影响哪些机器、哪些业务、持续了多久过程时间线 证据命令输出、日志改进监控补点、代码修复、预案更新复盘的粒度不必精雕细琢但一定要当场写完。拖到第二天细节就模糊了再想写就得靠脑补那还不如不写。5.3 沉淀一套应急预案把经验变成团队能力最后一点是我觉得最值得投入的事把高频故障的处理过程固化成应急预案。比如“磁盘告警应急预案”“CPU 飙高应急预案”每个预案里写清楚三块第一第一响应人 5 分钟内该跑哪些命令第二哪些操作禁止做比如 OOM 时不要盲目重启第三什么时候需要升级到 P1。预案的价值在于它能让你在凌晨三点半脑子不清醒的时候依然按照合理的顺序操作。个人经验再多也会被情绪影响但一条写好的流程不会。把这份文档维护在团队文档中心每次故障后更新一次半年之后你会发现大部分问题都有章可循。写到这里最后还是分享一个我自己的习惯每次处理完故障我都会把snapshot.sh生成的快照文件整理进故障归档目录文件名带上日期和故障编号。这活儿看起来不起眼但真有同事在三个月后回头查“上次磁盘满的时候那台机器的负载曲线到底长什么样”这套归档就成了珍贵的佐证材料。故障排查是一门经验学科经验从哪来就是从一次次快照、日志、复盘里攒出来的。你把这个闭环跑顺了告警再来时就真没啥可怕的了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。