ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux服务器故障排查实战:从CPU、内存、磁盘到网络的分层定位与避坑指南

Linux服务器故障排查实战:从CPU、内存、磁盘到网络的分层定位与避坑指南 简介这是一份面向Linux/Unix运维人员与系统管理员的故障排查实战资料以PDF形式整理聚焦服务器日常运维中高频出现的典型故障场景适合有一定Linux基础、希望提升排障能力的读者参考。资源包共1个PDF文件大小约367KB内容围绕磁盘挂载、系统引导、文件系统修复、依赖库管理及存储空间管理等方向展开涵盖RAID1数据分区挂载异常、root用户无法登录、GRUB分区误删导致双系统启动失败、硬盘移除后进入紧急模式、FreeBSD jail虚拟机/usr目录被填满等真实案例并附有/etc/fstab配置、fsck检查、单用户模式修复、网络引导与MBR修复等具体处理思路。目前已有92人学习浏览。读者可从中获得贴近生产环境的排错经验与操作参考理解故障成因与修复逻辑逐步建立系统化的服务器故障应对思路适合作为运维人员日常查阅与经验积累的辅助材料。1. 从一台“假死”的 Linux 服务器说起故障篇到底在讲什么凌晨两点,监控告警说一台跑了三年业务的生产服务器 ping 不通了,但机房现场看电源灯、网口灯都正常,风扇也在转。你 SSH 上去,连接超时;接上 KVM,发现系统卡在某个进程的 D 状态,负载飙到 200 多,dmesg里刷着一串 I/O error。这种“硬件看着没坏、系统却像死了一样”的场景,就是 Linux 服务器故障排查最典型的战场。所谓“明明白白你的 Linux 服务器-故障篇”,讲的不是背命令,而是建立一套从现象到根因的定位路径:CPU、内存、磁盘、网络、内核、服务,每一层都有它的“黑匣子”,关键是知道先看哪个、再看哪个。这篇内容适合日常要扛生产环境的运维、后端和 SRE,也适合正在准备 Linux 面试题、想把零散命令串成体系的人。下面我按自己踩过坑的顺序,把故障定位拆成能照着做的步骤。2. 故障定位的底层逻辑:先分层,再收敛排查故障最怕的不是不会命令,而是东一榔头西一棒子,top看一眼、ping一下、重启试试,最后问题复现了还是不知道根因。我一般会先把故障按“资源层 → 内核层 → 服务层 → 网络层”分层,再逐层收敛。这一章先把这套逻辑讲清楚,后面几章再落到具体命令和参数。2.1 为什么“重启大法”会掩盖真正的故障重启能恢复服务,但它把现场证据全抹掉了。Linux 的很多故障是渐进式的:磁盘坏道慢慢增多、内存泄漏逐步累积、文件描述符悄悄耗尽。重启之后这些计数器归零,你下次只能等它再犯。所以我的习惯是,只要不是业务完全中断,先抓现场再动手。抓现场的核心是三类数据:瞬时状态、历史趋势、内核日志。瞬时状态用top、vmstat、ss这类命令;历史趋势靠sar、atop或者监控系统;内核日志就是dmesg和/var/log/messages。这三类数据凑齐,基本能判断故障发生在哪一层。一个反直觉的结论是:CPU 高不一定怪 CPU。top里%wa(I/O 等待)高,说明 CPU 在等磁盘,根因在存储;%si(软中断)高,往往和网络收包有关。只看%us就下结论,十有八九会翻车。2.2 一套可复用的四步收敛法我把日常排查固定成四步,熟练之后大部分故障能在十分钟内定位方向。第一步,确认故障范围。是单机还是集群?是单服务还是全站?如果是集群里只有一台异常,先怀疑这台机器的硬件或配置漂移;如果全集群同时异常,优先看共享依赖,比如 NAS 存储、时间服务器、DNS。第二步,看负载三件套。uptime看 1/5/15 分钟负载趋势,vmstat 1看 CPU、内存、I/O、上下文切换,iostat -x 1看每块盘的%util和await。这三条命令一起跑,能快速区分是计算密集、内存不足还是磁盘瓶颈。第三步,定位到具体进程。用pidstat或者top -H找到吃资源的线程,再strace -p跟一下系统调用,看它卡在哪个 syscall 上。D 状态进程基本都卡在 I/O,这时候回到iostat看是哪块盘。第四步,查内核日志。dmesg -T带时间戳看,重点搜error、fail、timeout、reset。磁盘、网卡、RAID 卡的故障几乎都会在这里留痕。# 一次性抓取负载三件套,输出到文件方便对比 uptime /tmp/diag_$(date %s).log vmstat 1 5 /tmp/diag_$(date %s).log iostat -x 1 5 /tmp/diag_$(date %s).log dmesg -T | tail -100 /tmp/diag_$(date %s).log这段脚本的价值在于把同一时刻的多维数据落到一个文件里,事后复盘时时间线对得上。vmstat 1 5表示每秒采样一次共五次,iostat -x的-x是扩展统计,能看到await(平均等待毫秒)和%util(设备繁忙度)。%util长期接近 100 说明磁盘是瓶颈,await超过 20ms 在机械盘上就该警惕了。提示:采样间隔别设太长,1 秒足够捕捉突发;但排查内存泄漏这种慢故障,间隔要拉到分钟级,否则看不出趋势。3. CPU 与内存故障:从负载飙高到 OOM 的完整链路CPU 和内存故障占了日常问题的一大半,而且两者经常互相伪装。内存不够会触发 swap,swap 一上磁盘 I/O 就爆,表现出来却像 CPU 卡。这一章把这条链路拆开讲。3.1 负载高但 CPU 空闲:先分清三种“高”uptime里的负载值包含运行态和不可中断态(D 状态)进程。所以负载高有两种可能:真在算,或者在等 I/O。用vmstat 1看第一行的r(运行队列)和b(阻塞进程)就能区分。r大是 CPU 不够,b大是 I/O 卡住。还有一种情况是%st(被宿主机偷走的时间)高,这在服务器虚拟化环境里很常见。你的虚拟机看着 CPU 不满,但实际算力被同宿主机上的其他实例抢走了。这时候在虚拟机里怎么调都没用,得找虚拟化平台那边看资源超分情况。# 区分 CPU 真忙还是假忙 vmstat 1 10 # 关注列:r(运行队列) b(阻塞) us(用户态) sy(内核态) wa(IO等待) st(被偷走)如果us高,用top按 P 排序找进程,再用perf top看热点函数。如果sy高,多半是系统调用或中断频繁,查strace -c -p PID统计 syscall 分布。如果wa高,直接跳到第 4 章看磁盘。3.2 OOM Killer 触发后怎么还原现场内存耗尽时内核会启动 OOM Killer 杀进程,这是最容易被误判的故障——业务进程突然消失,日志里却没有崩溃堆栈。真相在dmesg里。# 查 OOM 记录 dmesg -T | grep -i out of memory grep -i killed process /var/log/messages输出里会写明被杀进程的 PID、名字、占用内存和总内存。看到这个先别急着加内存,要判断是进程真的需要这么多,还是泄漏了。用ps aux --sort-%mem | head看当前内存大户,再对比历史监控。判断泄漏有个土办法:连续采样 RSS。# 每 10 秒记录一次目标进程的 RSS,观察是否单调上涨 while true; do ps -o rss -p $(pgrep -f your_app) /tmp/rss.log sleep 10 doneRSS 持续上涨且不回落,基本就是泄漏。ps -o rss只输出数值不带表头,方便后续用脚本画图。pgrep -f按完整命令行匹配进程,比pgrep按进程名更准,避免匹配到同名进程。注意:调整vm.overcommit_memory和vm.swappiness能缓解症状,但别把它当解药。swappiness调到 0 只是尽量不用 swap,内存真不够时 OOM 照样来。3.3 内存参数怎么设才不背锅几个常被问到的内核参数,我给一组生产环境常用的值,但强调一句:没有万能值,得按业务压测。参数常用值作用调整风险vm.swappiness10降低 swap 倾向设 0 在内存紧张时可能直接 OOMvm.overcommit_memory0启发式允许超额分配设 1 会让 malloc 永不失败,风险高vm.dirty_ratio20脏页占内存上限太大导致突发写盘卡顿vm.min_free_kbytes内存的 1%~2%保留空闲页太小影响中断分配内存改之前先sysctl -a | grep vm.看现状,改完用sysctl -p生效,并写进/etc/sysctl.d/下的配置文件,否则重启就丢。4. 磁盘与 RAID 故障:从 I/O 报错到阵列卡掉盘磁盘故障是 Linux 服务器里最“诚实”的故障——它一定会留日志,但前提是你得知道去哪看。这一章从单盘 I/O 错误讲到 RAID 阵列卡,包括热词里常出现的lsi-9361-8i这类卡。4.1 用 iostat 和 dmesg 锁定坏盘磁盘出问题的第一信号通常是dmesg里的 I/O error,或者应用报“read-only file system”。文件系统变只读,基本是内核检测到不可恢复的写错误,主动保护数据。# 看每块盘的详细 I/O 指标 iostat -x 1 5 # 关注:r/s w/s await svctm %util # 看内核有没有报盘错误 dmesg -T | grep -iE I/O error|medium error|sense keyawait是平均每次 I/O 的等待时间(含排队),svctm是设备处理时间。如果await远大于svctm,说明排队严重,可能是盘慢或者队列太深。%util接近 100 且await高,这块盘就是瓶颈。dmesg里如果出现sd 0:0:0:0: [sda] Sense Key : Medium Error,说明盘上有坏扇区。这时候用smartctl看健康状态。# 需要 smartmontools smartctl -a /dev/sda | grep -iE Reallocated|Pending|Uncorrectable|Health重点看三个值:Reallocated_Sector_Ct(已重映射扇区)、Current_Pending_Sector(待重映射)、Offline_Uncorrectable(无法纠正)。任何一个非零且持续增长,这块盘就该换了。SMART overall-health显示PASSED不代表没问题,它只是没到阈值。4.2 RAID 卡掉盘后怎么定位到系统盘符这是热词里问得最多的问题:阵列卡上掉了一块盘,但系统里lsblk看到的是一整块逻辑盘,怎么知道是哪块物理盘坏了?以lsi-9361-8i这类 MegaRAID 卡为例,得用厂商工具。# 安装 storcli(具体包名按发行版) # 查看控制器和虚拟盘 storcli /c0 show # 查看物理盘状态 storcli /c0/eall/sall show # 查看某块物理盘详情 storcli /c0/e252/s0 show allstorcli /c0 show里看VD LIST(虚拟盘)和PD LIST(物理盘)。物理盘状态列State如果是UGood是正常,UBad或Offline就是掉了。EID:Slt是机箱号和槽位号,拿着这个去机房拔盘最准。关键的一步是把物理盘和系统盘符对应起来。RAID 卡通常会把每块物理盘也暴露成一个/dev/sdX,但顺序不一定和槽位一致。用smartctl反查:# 遍历所有盘,看序列号,和 storcli 里的序列号对上 for d in /dev/sd?; do echo $d smartctl -i $d | grep -iE Serial|Device Model donesmartctl -i输出的序列号,和storcli里物理盘的SN字段一致,就能确定/dev/sdb对应哪个槽位。这招在换盘时能避免拔错盘——拔错一块在跑的盘,RAID5 直接降级甚至崩掉,血泪经验。注意:RAID0 没有冗余,掉一块盘整个阵列就废了。热词里“硬盘做的 raid0”要特别小心,它性能好但零容错,生产环境除非数据可重建,否则别用。4.3 文件系统层面的排查盘没问题但文件系统报错,常见的是ext4的journal问题或者xfs的元数据损坏。先看挂载状态:mount | grep -E ro,|errors # 如果看到 ro 挂载,说明文件系统被内核置为只读修复要卸载后做,fsck对 ext4,xfs_repair对 xfs。但生产环境卸载意味着业务中断,所以更稳的做法是提前用tune2fs -l看文件系统状态,或者定期做只读检查。# ext4 查看文件系统状态 tune2fs -l /dev/sda1 | grep -iE state|error # 输出 clean 是正常,not clean 说明上次没正常卸载5. 网络与服务故障:ping 不通和“一般故障”怎么破网络故障的迷惑性在于,链路每一段都可能有问题,而报错信息往往很笼统。热词里“ping 内网显示一般故障”“ping 出现一般故障”就是典型——Windows 的 ping 报“一般故障”通常指本地协议栈或路由问题,Linux 下则要具体看。5.1 从 ping 不通到定位到具体网卡排查顺序永远是:本机协议栈 → 网关 → 目标。先ping 127.0.0.1确认协议栈正常,再ping 本机 IP确认网卡配置,再ping 网关确认二层可达,最后ping 目标。ip addr show ip route show ping -c 4 127.0.0.1 ping -c 4 $(hostname -I | awk {print $1}) ping -c 4 $(ip route | awk /default/{print $3})如果本机 IP 都 ping 不通,看ip addr里网卡是不是DOWN,或者 IP 没配上。如果网关不通,看ip route有没有默认路由,以及 ARP 表ip neigh里网关的 MAC 是否正常。ARP 显示FAILED说明二层就不通,可能是网线、交换机端口或 VLAN 问题。ethtool能看网卡物理层状态:ethtool eth0 | grep -iE Speed|Duplex|Link detected ethtool -S eth0 | grep -iE error|drop|discardLink detected: yes才说明物理链路通。-S里的rx_errors、tx_errors、rx_dropped持续增长,说明有丢包,可能是网线质量、双工不匹配或者网卡驱动问题。5.2 服务端口不通的排查路径ping 通但服务连不上,问题在端口或防火墙。按这个顺序查:# 1. 服务有没有监听 ss -tlnp | grep :8080 # 2. 本机能不能连自己 telnet 127.0.0.1 8080 # 3. 防火墙规则 iptables -L -n -v # 4. 如果是 firewalld firewall-cmd --list-allss -tlnp里-t是 TCP,-l是监听,-n是数字显示端口,-p显示进程。如果服务没监听,问题在应用本身;如果监听了但连不上,看是不是绑在了127.0.0.1而不是0.0.0.0。这个坑很常见——配置里写了bind 127.0.0.1,外部自然连不上。防火墙这块,iptables -L -n -v的-v能看到每条规则的包计数,如果某条 DROP 规则计数在涨,就是它拦的。云服务器还要额外看安全组,那是平台层的,机器里看不到。5.3 集群故障转移与时间服务器集群环境里,单机网络正常但集群异常,优先查两个东西:心跳网络和时间同步。心跳网络断了,节点会误判对方宕机,触发脑裂或误切换。时间不同步,会导致证书校验失败、日志时间错乱、分布式锁异常。# 看时间同步状态 timedatectl chronyc sources -v # 或 ntpq -ptimedatectl里System clock synchronized: yes才算正常。chronyc sources里看^*标记的才是当前同步源,如果全是^?说明一个都没连上。国内环境常用内网时间服务器,配置在/etc/chrony.conf里,改完systemctl restart chronyd。提示:集群节点时间偏差超过阈值(通常几十毫秒),很多分布式组件会直接拒绝服务。别等出故障才查,监控里加一条时间偏移告警。6. 避坑与排查:五条踩出来的经验前面讲的是方法,这一章讲我实际踩过的坑。每条都按“现象 → 原因 → 解决”写,方便你对号入座。第一条:进程 D 状态杀不掉。现象:kill -9一个进程没反应,ps看状态是D。 原因:D 状态是不可中断睡眠,进程卡在内核态等 I/O,信号要等系统调用返回才处理。这时候杀它没用,得先解决它等的 I/O。 解决:用cat /proc/PID/stack看内核栈,确认卡在哪个设备;再用iostat找到那块盘。盘恢复或超时后进程自己会退出。硬重启是最后手段。第二条:磁盘满了但du统计对不上。现象:df显示根分区 100%,但du -sh /*加起来远不到。 原因:有进程删了文件但文件句柄没释放,空间被已删除的 inode 占着。 解决:lsof | grep deleted找到持有句柄的进程,重启它或者 /proc/PID/fd/N清空。预防办法是日志用 logrotate 而不是直接 rm。第三条:改内核参数后没生效。现象:sysctl -w改了值,重启后变回去。 原因:sysctl -w只改运行时,不写配置文件。 解决:写进/etc/sysctl.d/99-custom.conf,再sysctl -p /etc/sysctl.d/99-custom.conf。注意文件名排序,后面的会覆盖前面的。第四条:RAID 换盘拔错槽位。现象:换盘后阵列没恢复,反而又掉一块。 原因:没把物理槽位和系统盘符对应上,凭感觉拔。 解决:换盘前一定用storcli看EID:Slt,再用smartctl序列号反查系统盘符,双重确认。拔之前再看一眼阵列状态。第五条:ping 通但应用超时。现象:网络层全通,应用层请求超时。 原因:可能是 MTU 不匹配,大包被丢。或者连接数打满,ss -s看TIME_WAIT数量。 解决:用ping -M do -s 1472测 MTU,不通就调小网卡 MTU。连接数问题调net.ipv4.tcp_tw_reuse和文件描述符上限。7. 把故障排查变成可复用的脚本与习惯排查能力最终要沉淀成两样东西:一套随手能跑的采集脚本,和一个每次故障后更新的检查清单。我现在的习惯是,每台新上线的服务器都放一个diag.sh,出问题时一条命令抓全现场,而不是手忙脚乱敲十几条命令。#!/bin/bash # diag.sh - 一键采集故障现场 OUT/tmp/diag_$(hostname)_$(date %Y%m%d_%H%M%S) mkdir -p $OUT uptime $OUT/uptime.txt free -m $OUT/mem.txt vmstat 1 5 $OUT/vmstat.txt iostat -x 1 5 $OUT/iostat.txt ss -s $OUT/socket_summary.txt ss -tlnp $OUT/listen.txt dmesg -T | tail -200 $OUT/dmesg.txt ps aux --sort-%cpu | head -20 $OUT/top_cpu.txt ps aux --sort-%mem | head -20 $OUT/top_mem.txt df -h $OUT/disk.txt ip addr $OUT/ip.txt ip route $OUT/route.txt echo 采集完成,输出目录: $OUT tar czf $OUT.tar.gz $OUT echo 已打包: $OUT.tar.gz这个脚本的每个命令都对应前面讲的一层:内存、CPU、I/O、连接、监听、内核日志、进程、磁盘、网络。ps aux --sort-%cpu按 CPU 降序取前 20,--sort-%mem同理。打包成 tar.gz 是为了方便传给同事或存档。注意脚本本身别放在会被日志写满的分区上。比脚本更重要的是习惯。我给自己定了三条:第一,任何故障处理完,当天把根因和排查路径写进笔记,尤其是那些“差点误判”的瞬间;第二,监控告警的阈值要跟着故障复盘调整,别让同一个坑踩两次;第三,定期做故障演练,手动制造磁盘满、进程 OOM、网络丢包,练到条件反射。排查这事没有捷径,靠的就是把每次翻车都变成下一次的后悔药。希望帮到你。本文还有配套的精品资源点击获取
返回列表