当前位置:首页>Linux>每日一学:Linux服务器突然卡了?5个排查步骤一次搞定

每日一学:Linux服务器突然卡了?5个排查步骤一次搞定

  • 2026-10-11 06:06:02
每日一学:Linux服务器突然卡了?5个排查步骤一次搞定

Linux服务器突然卡了?5个排查步骤一次搞定

场景引入

你一定遇到过这样的场景:周一早上刚到工位,手机就炸了——客户反馈网站打不开,老板在群里@你,同事焦急地催你。你赶紧SSH登录服务器,发现敲命令后要等好几秒才有反应,ls 都卡顿,top 命令更是转了十几秒才出来。更糟的是,你连 reboot 都不敢执行,怕万一重启后起不来了。

这种“服务器突然卡了”的紧急情况,是每个运维人都会遇到的噩梦。别慌,今天我就带你走一遍完整排查流程,5个步骤让你从“手抖”变成“稳如老狗”。

问题复现

我们先模拟一个典型的“卡顿”场景。假设你有一台跑着Nginx + PHP-FPM + MySQL的Web服务器,突然某个时段CPU飙升到100%,所有请求都超时。

登录后,你执行 top 命令,看到类似这样的输出:

top - 10:15:30 up 3 days, 2:10,  1 user,  load average: 15.20, 12.80, 10.50Tasks: 250 total,   3 running, 247 sleeping,   0 stopped,   0 zombie%Cpu(s): 95.0 us,  3.0 sy,  0.0 ni, 0.0 id,  2.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem :  8000000 total,   200000 free,  6000000 used,  1800000 buff/cacheKiB Swap:  2000000 total,  1500000 used,   500000 free,   5000 avail Mem  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 1234 www-data  20   0  500000 200000  10000 R  85.0  2.5   5:30.12 php-fpm 5678 www-data  20   0  500000 180000  10000 R  80.0  2.2   4:20.05 php-fpm 9012 mysql     20   0 1500000 500000  30000 S  20.0  6.2  10:00.00 mysqld

关键指标:

  • • load average 高达15(你的CPU只有4核),远超正常值
  • • CPU空闲率 0%,用户态占用95%
  • • 内存 几乎耗尽,Swap用了75%
  • • PHP-FPM进程 占用了绝大部分CPU

这就是典型的“CPU打满 + 内存不足”导致服务器卡顿的现场。

原因分析

要理解为什么服务器会卡,我们需要从操作系统底层原理讲起。这里我用一个“厨房”的比喻帮你理解。

CPU——厨师

CPU就像厨房里的大厨,负责处理所有计算任务。每个进程(PHP、MySQL等)就像一道道菜。当同时来太多菜(进程数超过CPU核心数),大厨就得在菜之间频繁切换(上下文切换),切换本身也消耗时间。如果某个菜特别耗时间(比如PHP代码死循环),其他菜就得排队等着。

内存——备菜台

内存是厨师的操作台,上面放着各种食材和工具。如果操作台太小(内存不足),厨师就得频繁去仓库(磁盘)取东西。仓库取东西比从操作台拿慢1000倍以上(磁盘IO vs 内存访问)。

Swap——临时仓库

当备菜台放不下时,系统会把暂时不用的食材搬到仓库(Swap分区)。但仓库取东西极慢,频繁的Swap操作会导致系统像“死机”一样。

磁盘IO——传菜通道

磁盘IO就像传菜员,如果传菜通道被堵死(大量读写请求),厨师拿到食材的速度就会变慢,整个厨房效率下降。

网络——外卖窗口

网络是外卖窗口,如果窗口被堵住(大量连接),厨师做好菜也送不出去,导致请求堆积。

回到我们的例子:

  1. 1. PHP-FPM进程 占用了85%的CPU,说明PHP代码可能陷入死循环或执行了极慢的SQL查询
  2. 2. 内存 被大量消耗,Swap使用率75%,说明物理内存不够,系统在频繁换页
  3. 3. 磁盘IO 可能很高(多个进程在读写),进一步拖慢整体性能

这种“连锁反应”导致服务器响应越来越慢,最终“卡死”。

解决方案

下面我们分5个步骤来排查和解决。每个步骤都包含实际命令和操作。

步骤1:快速定位资源瓶颈

首先,用 top 或 htop 观察整体资源使用情况,然后用 vmstat 和 iostat 深入分析。

# 每2秒刷新一次,观察CPU、内存、IOvmstat 2 5# 输出示例(重点关注最后一列 wa):# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----#  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st#  5  2 1500000 200000 300000 1500000  100  200   500   300  500 2000 95  3  0  2  0

关键指标解读:

  • • r(running):等待CPU的进程数。如果 > CPU核心数,说明CPU是瓶颈
  • • b(blocked):被IO阻塞的进程数。如果 > 0,说明磁盘IO有问题
  • • si/so(swap in/out):如果持续 > 0,说明内存不足
  • • wa(wait IO):CPU等待IO的时间。如果 > 10%,磁盘IO可能是瓶颈
# 查看磁盘IO详情iostat -x 2 5# 输出示例:# Device:   rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util# sda        0.00     0.00   100.00  200.00  1000.00  2000.00    20.00     5.00   20.00   10.00   25.00   2.00  60.00

关键指标:

  • • await:平均IO等待时间(毫秒)。机械盘通常 < 10ms,SSD < 1ms
  • • %util:磁盘利用率。接近100%说明磁盘饱和

💡 重要提示:如果 %util 接近100%但 await 不高,说明磁盘性能足够,是请求过多导致排队。如果 await 很高,说明磁盘本身慢(如老机械盘)。

步骤2:找出消耗CPU的进程

用 top 按 P 键(大写P)按CPU使用率排序。找到可疑进程后,用 strace 追踪系统调用:

# 假设PID 1234是消耗CPU最多的进程strace -p 1234 -c -S time 2>&1 | head -20# 输出示例:# % time     seconds  usecs/call     calls    errors syscall# ------ ----------- ----------- --------- --------- ----------------#  50.00    0.500000        1000       500         0 read#  30.00    0.300000        1500       200         0 write#  15.00    0.150000        3000        50         0 connect

如果发现 read 系统调用耗时最多,说明进程在等待IO(如慢SQL查询)。如果 connect 多,可能是网络请求阻塞。

另一个工具是 perf,可以采样分析CPU热点:

# 采样10秒perf record -g -p 1234 -- sleep 10perf report

💡 重要提示:strace 会降低进程性能,生产环境谨慎使用。可以先观察CPU占用的函数名,再决定是否追踪。

步骤3:检查内存和Swap使用

用 free -h 和 smem 查看内存详情:

free -h#               total        used        free      shared  buff/cache   available# Mem:           7.8G        5.9G        200M        100M        1.7G        1.2G# Swap:          2.0G        1.5G        500M# 查看每个进程的内存占用(按RSS排序)ps aux --sort=-%mem | head -10

如果Swap使用率 > 50%,说明物理内存严重不足。可以用 vmstat 观察 si/so 列是否持续 > 0。

临时缓解方案:

# 清空pagecache(谨慎使用,会降低后续性能)echo 1 > /proc/sys/vm/drop_caches# 或者清空dentries和inodesecho 2 > /proc/sys/vm/drop_caches# 同时清空echo 3 > /proc/sys/vm/drop_caches

⚠️ 警告:drop_caches 是临时措施,不会释放Swap。长期方案是增加物理内存或优化应用内存使用。

步骤4:检查磁盘IO和文件系统

用 iotop 实时查看哪个进程在读写磁盘:

# 需要root权限iotop -o -P# 输出示例:# Total DISK READ :       0.00 B/s | Total DISK WRITE :       2.00 M/s# Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       2.00 M/s#   PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND#  1234 be/4 www-data   0.00 B/s    1.00 M/s   0.00 %  50.00 %  php-fpm: pool www#  5678 be/4 mysql      0.00 B/s    1.00 M/s   0.00 %  30.00 %  mysqld

如果发现某个进程IO很高,可以用 lsof 查看它打开了哪些文件:

lsof -p 1234

磁盘空间检查:

df -h# 如果某个分区使用率 > 90%,可能导致性能下降# 查找大文件du -sh /* 2>/dev/null | sort -rh | head -10

步骤5:检查网络连接和进程状态

用 netstat 或 ss 查看网络连接状态:

# 查看TCP连接状态统计ss -s# 输出示例:# Total: 1000 (kernel 1024)# TCP:   500 (estab 300, closed 100, orphaned 50, synrecv 10, timewait 40)# 查看具体连接ss -tan | awk '{print $1}' | sort | uniq -c#   300 ESTAB#    50 TIME-WAIT#    10 SYN-RECV

如果 SYN-RECV 数量很多,可能是遭受SYN洪水攻击。如果 TIME-WAIT 过多,需要调整内核参数。

检查进程状态:

# 查看D状态(不可中断睡眠)的进程ps aux | grep " D"

D状态进程通常表示等待磁盘IO完成。如果数量 > 5,磁盘IO很可能有问题。

对比不同方案的优缺点

排查工具
优点
缺点
适用场景
top
实时、全面、自带
信息太多,需要筛选
第一眼观察
vmstat
轻量、系统级
不显示进程级
CPU/内存/IO综合判断
iostat
磁盘IO详细
需要安装sysstat
磁盘性能分析
strace
进程级追踪
性能开销大
定位具体问题进程
perf
低开销采样
需要内核支持
CPU热点分析
iotop
进程级IO显示
需要root权限
找出IO大户
ss
比netstat更快
参数略复杂
网络连接排查

扩展知识

内核参数调优

如果频繁遇到连接数过多或TIME-WAIT堆积,可以调整以下内核参数:

# 快速回收TIME-WAIT连接echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.confecho "net.ipv4.tcp_tw_recycle = 1" >> /etc/sysctl.conf  # 注意:NAT环境下慎用# 调整最大文件句柄数echo "fs.file-max = 655350" >> /etc/sysctl.conf# 应用配置sysctl -p

日志分析

卡顿问题往往在日志中有线索:

# 查看系统日志journalctl -xe --since "1 hour ago" | grep -i error# 查看应用日志(以Nginx为例)tail -f /var/log/nginx/error.log# 慢查询日志(MySQL)tail -f /var/log/mysql/slow-query.log

进阶学习建议

  1. 1. 性能分析工具集:学习使用 bcc(BPF Compiler Collection)工具,如 biosnoop、execsnoop 等
  2. 2. 内核源码:理解进程调度、内存管理、IO栈的底层实现
  3. 3. 监控系统:搭建Prometheus + Grafana,实现可视化监控和告警
  4. 4. 压测工具:掌握 ab、wrk、sysbench 等压测工具,主动发现性能瓶颈

互动话题

📞 凌晨的告警声,你最怕听到什么?
是CPU爆了、内存 leak,还是磁盘写满?
欢迎在评论区写下你经历过的最“刻骨铭心”的一次半夜救火,点赞最高的朋友,送一套《Linux运维命令地毯式排查表》电子版。

本文基于Linux内核5.10版本,CentOS 7/8和Ubuntu 20.04/22.04环境测试通过。不同发行版命令可能略有差异。

最新文章

随机文章