Linux系统中5分钟内找出问题
1. 先看整体健康状况和内核日志,直接排除硬件故障或内核panic。
# 1. 查看 Load Average 是否远超 CPU 核心数和 系统运行时间
uptime# 2. 看
available(可用内存)是否见底。看swap是否被大量占用。如果 swap 正在被频繁读写,说明物理内存早已被榨干,系统正处于极度卡顿的“颠簸”状态。
free -h# 3. 【最重要】查看内核最后输出的几十条日志(硬件错误、OOM、磁盘报错)
dmesg -T | tail -20快速判断:若
dmesg出现Out of memory、I/O error、segfault,直接定位根因,不用往下看
2. cpu、内存、进程
sudo ps aux | sort -rn -k +3 | head
sort -rn -k +3该命令中的-rn的r表示是结果倒序排列,n为以数值大小排序,而-k +3则是针对第3列的内容进行排序,第三列是 cpu,第四列是内存,再使用head命令获取默认前10行数据。(其中的|表示管道操作)
如果
free -h显示可用内存(available)很少,且交换分区(swap)使用量飙升,说明内存压力大。# 查看内存占用 TOP 10 的进程(按RSS排序) sudo ps aux --sort=-%mem | head -10 # 查看具体内存映射(若怀疑某个进程) cat /proc/[PID]/smaps | grep -i pss | sort -nr | head -10提示:如果系统突然变慢但内存剩余较多,检查
cat /proc/meminfo | grep -i "Dirty",脏页过多说明磁盘I/O刷写阻塞了内存分配。
按内存升序排列:ps aux --sort=rss
按CPU降序排列:ps aux --sort=-%cpu
--sort=[+|-] key
“+”字符是可选,因为默认地是按数字升序或者词典顺序.
top
top -d 1
- 按P:按 CPU 使用率排序
- 按M:按内存使用率排序
- 运行中按c,可以随时切换是否显示完整命令 【常用】
点亮显示,先按b 再按x
按z 反色显示
按? 找帮助
在 top 中紧盯这三项:
%us:用户态高 → 业务应用(如Java/Python)死循环或计算密集。
%sy:内核态高(>20%)→ 系统调用频繁,可能是上下文切换过高,用
vmstat 1 5查看cs(context switch)列。%wa:I/O等待高 →CPU在等磁盘,问题转向下面的磁盘排查。
僵尸进程(zombie):数量不为0,用
ps aux | grep 'Z'找出父进程。看
top里排在最前面的进程(PID),看它是 CPU 飙高,还是处于D状态(不可中断睡眠,通常意味着卡在磁盘 I/O 上)。
3. 磁盘
如果top中%wa高,或者应用响应卡顿,立即执行:
# -x 显示扩展信息,1 表示间隔1秒,2 表示输出2次
iostat -x 1 2iostat -dxk 1
vmstat 1
看
vmstat的procs下面的b列(等待输入输出的进程数)。如果b大于 0,说明有进程卡在磁盘写入上。
关键列:
%util:接近 100% → 磁盘设备饱和(带宽打满)。
await(平均等待时间):> 20ms 表明磁盘响应慢,> 100ms 表明严重I/O拥堵。
查找具体哪个进程在读写:
sudo iotop -o(直接列出实际产生I/O的进程)。
df -h -x tmpfs -x devtmpfs
df -i
看是否有分区的Use%达到了100%
看IUse%(Inode 使用率)是否达到了 100%
df -T:这是最直接的方法,可以查看所有已挂载文件系统的类型
cat/proc/filesystems:查看系统支持的文件系统类型。如果一个文件系统被标记为nodev,表示它不需要关联物理设备(如虚拟文件系统、网络文件系统)
案例:磁盘爆满使用率已经100%了、I/O 锁死或根目录极度迟钝时,怎么找出哪个目录过大?
解决方法的核心逻辑是:通过将底层块设备挂载到一个干净、全新的挂载点(如/mnt),绕过了原有挂载点上可能存在的繁重业务 I/O 读写和软链接干扰。
在 Linux 运维中被称为“影子挂载”或“双重挂载”。它的核心精妙之处在于:在 Linux 中,同一个底层块设备(Block Device)是可以同时被挂载到多个不同的目录(挂载点)上的。
[root@kaifa ~]# df -h Filesystem Size Used Avail Use% Mounted on ... /dev/mapper/cl-root 37G 17G 21G 46% / /dev/sdb2 976G 164G 745G 19% /var正常状态下:
/dev/sdb2挂载在/var上。所有业务程序(如 Nginx、MySQL)都通过/var这扇大门向磁盘写入数据。此时这扇门人满为患,I/O 请求排起长队,大门(文件系统元数据锁)被严重占用。影子挂载后:你执行
mount /dev/sdb2 /mnt,相当于为同一个物理盘又开了一扇叫/mnt的“后门”。
当你通过/mnt进去时,你看到的内容和/var完全一样,但你走的是一条完全没有业务流量堵塞的专用绿色通道。
为什么能绕过“繁重的业务 I/O 读写”?
当磁盘 100% 满且有程序疯狂写入时,原挂载点(如/var)会面临严重的元数据锁(Metadata Lock)竞争。
在原目录查找的困境:如果你直接在
/var下执行du -sh,系统不仅要读取文件大小,还要频繁与正在疯狂写入的业务进程竞争目录的读取锁。由于 I/O 已经满载,du命令发送的内核请求只能在队列里死等,表现出来就是命令完全卡死。在影子目录查找的优势:文件系统(如 Ext4、XFS)内部有不同的路径缓存和索引机制。通过
/mnt访问时,你避开了原目录树(Directory Tree)上被高频修改的节点锁。虽然底层的物理磁头/固态硬盘通道依然繁忙,但在操作系统内核的软件层面,你成功绕过了严重的进程上下文切换和文件锁挂载点阻塞,从而能以快得多的速度返回结果。
处理过程
# 配合“只读挂载(ro)”实现完美隔离 mount -o ro /dev/sdb2 /mnt 或者 mount /dev/sdb2 /mnt mount --bind /dev/sdb2 /mnt # 挂载成功后,你就可以直接进入 /mnt/ 开启你的超速排查通道了 du -h -x --max-depth=1 /mnt/ 2>/dev/null | sort -hr | head -n 10 # 加上 -x (或 --one-file-system) 参数,可以让 du 只在当前文件系统内扫描,绝对不跨越到其他分区或挂载点 find / -xdev -type f -size +500M 2>/dev/null | xargs du -h | sort -hr | head -n 10 # -xdev:同样是限制在当前文件系统内,不跨分区。 方法一: find -maxdepth 1 -print0 | xargs -0i du -hs {} | sort -rh | head -11 | cut -f2 | xargs -i du -hs {} # find -maxdepth 1 -print0:在当前目录(深度为 1,不往子目录深挖)查找所有文件和文件夹。-print0 表示用 \0(空字符)作为分隔符,这是为了防止文件名里有空格导致命令断开。 # xargs -0i du -hs {}:-0 配合前面的 print0 接收空格文件名;i 和 {} 配合,把前面找到的路径一个一个喂给 du -hs(计算人类可读的大小,如 1G, 500M)。 mount /dev/sdb2 /mnt/ cd /mnt/ find -maxdepth 1 -print0 | xargs -0i du -hs {} | sort -rh | head -11 | cut -f2 | xargs -i du -hs {} cd umount /mnt/ exit 方法二: 根据cat /etc/fstab |grep -v "^#" 排除不是真正在/ 目录的文件,特别地, 要去掉bind方式挂载的目录。 du -h /* --max-depth=0 \ --exclude="home" \ --exclude="var" \ --exclude="result" \ --exclude="pkg" \ --exclude="cephfs" 2>/dev/null | grep "G"找出已被删除但仍被进程占用的文件
lsof +L1
# 或者使用下面这个更直观的命令:
lsof | grep deleted
输出结果中会显示进程名(COMMAND)、进程 PID 以及被删除的文件名(带有(deleted)字样)。
抓到罪魁祸首(比如 PID 为1234的 nginx 进程)后,你有两种处理方式:
1. 重启该服务或让其重载配置。
2. 在线清空(如果不能重启服务):如果该进程在持续写入,且不能停机,可以通过它的 PID 直接在/proc目录下将其文件内容清空:
#文件描述符 ID 可以在
lsof的FD列看到,通常是个数字echo "" > /proc/1234/fd/文件描述符ID
# 或者,不删文件释放空间
echo "" > /var/log/app.log
> /var/log/app.log
# 用
chattr锁死文件,不准任何进程写入chattr +i /var/log/app.log
# 解锁
chattr -i /var/log/app.log
4. 网络
如果应用返回超时或连接失败,快速检查网络层面。
# 1. 查看所有监听端口及连接状态(比 netstat 快)
ss -tulnp# 2. 统计 TIME_WAIT 或 CLOSE_WAIT 堆积(大量 CLOSE_WAIT 是代码未关闭连接)
ss -ant | awk '{print $1}' | sort | uniq -csudo ss -antp | grep CLOSE-WAIT | awk '{print $NF}'
# 3. 检查网卡丢包和错误(eth0替换为实际网卡名)
ip -s link show eth0特殊情况:如果
ifconfig显示overruns或dropped数量暴增,说明网卡缓冲区不足或硬件队列溢出。
查看 TCP 汇总:
ss -s -t查看 UDP 汇总:
ss -s -uss -s
快速查看整机所有网络连接数量概览,排查 TIME_WAIT、连接数过高问题。是否有大量的
TIME-WAIT(遭遇并发洪峰)或CLOSE_WAIT(应用程序代码网络泄漏)。
5. 其它
sudo grep -RniE "critical|error|fatal|panic|exception" /var/log/messages | grep -v "ACPI Error" ps -ef |grep thanos sudo grep -E "thanos\[12096\]:" /var/log/messages # 查看是否有 D 状态进程(重点看 WCHAN 栏卡在哪个内核函数,如 rwsem_down_write_failed, blk_wait_io, 进程正在内核中等待什么资源(显示等待的内核函数名)) ps -eo pid,ppid,stat,wchan,comm | grep -w D # 查看 I/O 队列长度和等待时间(如果 await 达到几百毫秒甚至上千毫秒,说明 I/O 彻底挂了) iostat -x 1 106. 查看Linux上启用的服务
| 需求 | 推荐命令 (systemd系统) | 备选命令 (SysVinit系统) |
|---|---|---|
| 查看正在运行的服务 | systemctl list-units --type=service --state=running | service --status-all |
| 查看开机自启的服务 | systemctl list-unit-files --type=service --state=enabled | chkconfig --list |
| 查看特定服务的状态 | systemctl status <服务名> | service <服务名> status |
如果不确定你的系统使用的是systemd还是SysVinit,可以运行pstree -p | head -n 2或ps -p 1来查看。如果输出中包含systemd,则说明系统使用的是systemd。
