服务器突然变慢怎么排查?从负载到磁盘的定位步骤
服务器突然变慢,先别急着重启。
重启会清掉现场,下次再出现更难查。
正确的做法是趁问题还在,按 CPU、内存、磁盘、网络四个方向逐项看指标,找到占用资源的具体进程再处理。
下面按实际操作顺序讲清楚每一步看什么、命令怎么用、结果怎么判断。
先确认是整台机器慢还是某个服务慢
登录服务器后,第一件事是分清范围。
如果 SSH 都卡顿、命令回显延迟,说明整机资源紧张;
如果 SSH 流畅但网站打不开,问题可能只在 Web 服务或数据库。
用 uptime 看最近 1、5、15 分钟的平均负载:
uptime
输出里的 load average 三个数字分别对应 1、5、15 分钟。
判断标准是拿它和 CPU 核心数比:nproc 查看核心数,负载持续超过核心数的 1.5 到 2 倍,通常说明有任务在排队。
负载高但 CPU 使用率不高,往往是磁盘 I/O 或大量进程等待造成的。
用 top 定位占用 CPU 和内存的进程
top 是最直接的入口,运行后按 P 按 CPU 排序、按 M 按内存排序:
top -b -n 1 | head -20
重点看三行:%Cpu(s) 里 us(用户进程)和 sy(系统内核)是否偏高;MiB Mem 里可用内存还剩多少;MiB Swap 是否在被大量使用。
如果 swap 用量持续上涨,说明物理内存不够,系统在拿磁盘当内存用,整体会明显变慢。
找到占用最高的 PID 后,用 ps 确认它是什么服务:
ps -p -o pid,user,%cpu,%mem,cmd
如果是某个 PHP-FPM 或 Java 进程长期占满单核,先看它的日志和访问量,不要直接 kill。
用 kill -15 发送正常终止信号,让进程自己退出;
确认无响应再用 kill -9。
磁盘 I/O 高是变慢的常见原因
CPU 看起来不高、内存也够,但命令就是慢,优先查磁盘。
用 iostat 看每块盘的读写等待:
iostat -x 1 3
关注 %util 和 await 两列。%util 接近 100% 说明磁盘接近满负荷;await 明显高于正常值(机械盘通常几毫秒到十几毫秒,SSD 更低)说明 I/O 在排队。
再配合 iotop 看是哪个进程在读写:
iotop -oPa
常见原因是日志文件暴涨、备份任务和业务高峰撞在一起、或者数据库慢查询导致大量临时文件读写。
先看 /var/log 下大文件,用 du -sh /var/log/* | sort -rh | head 定位,确认后再清理或切割日志,不要直接删正在写入的日志文件。
检查网络连接和端口状态
如果本地命令不慢,只是外部访问慢,查网络层。
用 ss 看连接数和端口监听:
ss -s
ss -tlnp | grep -E '80|443|3306'
ss -s 输出里 TIME-WAIT 数量过高,可能是短连接太多;ESTAB 数量接近系统上限,新连接会被拒绝或排队。
用 ss -tan state established | wc -l 统计当前已建立连接数,再对照 ulimit -n 的文件描述符上限。
如果连接数接近上限,需要调整服务配置或系统参数,而不是反复重启。
带宽打满也会表现为“服务器慢”。
用 iftop 或 nload 看实时流量,确认是否有异常外联或大文件下载占满带宽。
处理后的复查和避坑
处理完具体进程后,不要马上离开。
等 5 到 10 分钟,重新执行 uptime、top 和 iostat -x 1 3,确认负载和 I/O 等待回落到正常范围。
同时看服务日志有没有新的报错,比如 OOM(内存溢出)记录:
dmesg -T | grep -i 'out of memory'
如果看到 OOM killer 记录,说明内存确实不够,需要优化程序内存占用或增加内存,而不是只重启服务。
几个容易踩的坑:不要一上来就 reboot,现场丢失后无法定位根因;
不要看到 CPU 高就直接杀进程,先确认它是不是关键业务;
清理日志前先确认日志是否被程序占用,直接 rm 可能导致磁盘空间不释放,正确做法是 truncate -s 0 文件名 或通过日志服务切割。
服务器突然变慢多数不是单一原因,按“负载 → CPU/内存 → 磁盘 → 网络”的顺序逐层排除,每一步都有命令和判断依据,比凭感觉重启更可靠。
处理完记得复查指标,确认问题真正消失再结束。