服务器变慢先别重启:8 条命令,按顺序查下来

为什么「重启一下」是坏习惯

重启能解决大半的表面问题,代价是把证据全清干净了:进程没了、连接断了、日志里的计数器归零。第二天同一个时间点再卡一次,你还是一无所知,只能再重启一次。

下面 8 条命令有先后顺序:先确认「这台机器整体在不在正常范围」,再找「谁在吃资源」,最后定位「卡在哪一层」。每条都给判断标准,照着比对即可。所有命令在 Ubuntu / CentOS 都通用,不需要装任何东西(iostat 除外,属 sysstat 包)。

1. uptime:先看三个 load

uptime 输出里的 load average: 0.52, 1.31, 2.04 分别是 1、5、15 分钟的平均负载。

判断标准:load 接近 CPU 核数就算压满了。用 nproc 看核数。2 核机器 load 稳定在 2 以上就是在排队;4 核机器 load 到 40 基本等于不可用。

关键在于:load 高不等于 CPU 忙。load 统计的是「运行中」加「不可中断等待」的进程,等磁盘、等网络存储都算进去。所以 load 20 而 CPU 闲着,问题不在计算,在 IO 或内存。

三个数还要看趋势:15 分钟值 > 5 分钟值 > 1 分钟值 说明已经在恢复;反过来 1 分钟 > 15 分钟 说明正在恶化,别等了,直接往下查。

2. top:CPU 时间花在哪一类上

top 之后按 1 展开每个核,看顶部的 %Cpu(s) 一行:

  • us 高(用户态):业务代码在算,多半是某个 PHP / Java 进程
  • sy 高(内核态):系统调用多,常见于疯狂建连接、文件句柄暴涨
  • wa 高(IO 等待):磁盘拖住了,CPU 在发呆等数据
  • si + st 高:被虚拟化层抢走了(云主机的「超卖邻居」现象,只能换实例规格)

看进程用 top -b -n1 | head -20 直接刷新一次,比交互界面好复制。要按 CPU 排序:ps aux --sort=-%cpu | head;按内存:ps aux --sort=-%mem | head。

留意 STAT 一列:R 在跑,S 睡眠,D 是不可中断睡眠——进程状态出现大量 D,几乎一定是磁盘或网络存储卡住了,杀进程也杀不掉,得先解决 IO。

3. free:别把 buff/cache 当内存泄漏

free -m 最右边有一个 available,那才是真正还能用的内存。buff/cache 是被内核拿去做文件缓存的部分,它会在需要时立刻让出来,不是泄漏。只看 free 那一列然后惊呼「内存只剩 200M」,是新手最常见的误判。

真正要警惕的两个信号:

  • available 低于总内存的 10%,且 swap 的 used 持续上涨
  • dmesg -T | grep -i oom 出现 Out of memory: Killed process——内核已经动手杀进程了,被杀的常常是 MySQL,表现就是网站突然 502

4. df -h 和 df -i:空间够也可能写不进文件

df -h 看容量,df -i 看 inode。两者是独立的:inode 用满时,df -h 显示还有几十 G 空余,程序却报 No space left on device。

inode 爆掉几乎都是同一个原因:某个目录里有海量小文件。日志按秒切分、session 文件没清理、缓存目录堆了几百万个空文件,都会这样。定位:find /var/log -type f | wc -l 再逐层加目录看哪个数量级失控。

5. iostat:磁盘到底有多堵

iostat -x 1 3 每 1 秒采一次共 3 次,重点看两列:

  • %util:设备忙碌百分比,长期接近 100 说明请求在排队
  • await:平均等待毫秒数。机械盘超过 20ms、SSD 超过 10ms 就偏慢;上百 ms 属于严重拥堵

云主机的普通云盘 IOPS 本来就低(常见几百 IOPS),一个全表扫描的 SQL 就能把它打满。这时候 CPU 和内存都正常,网站却慢得打不开——wa 会把答案露出来。

6. ss:连接层出了什么事

ss -s 看总览,ss -lntp 看监听端口和哪个进程占着。

两个最常见的异常:

  • TIME_WAIT 上万个并且持续增长:短连接太多。检查代码里有没有每请求都新建一次数据库 / HTTP 连接,以及 net.ipv4.tcp_tw_reuse 之类参数是不是该调
  • Recv-Q / Send-Q 堆积:监听端口的 Send-Q 是 backlog 上限,Recv-Q 超过它就是「连上来但没人 accept」——应用进程卡住了,不是网络问题

「端口通不通」这类判断可以先用 端口速查 对照常见服务端口,别把 3306 当成 3307 查半天。

7. 日志:内核和服务的原话

  • journalctl -p err -n 50 --no-pager:最近的错误级日志
  • dmesg -T | tail -50:内核层面的事故,OOM、磁盘错误、网卡重置都在这
  • Nginx 的 error.log、PHP-FPM 的 error.log、MySQL 的 slow.log——三个文件分别回答「请求卡在哪」「脚本报了什么」「哪条 SQL 拖死了数据库」

顺着日志里的时间点,回头对一下 uptime 的 load 曲线,两边能对上就基本定案了。

8. 502 和 504 的区别,一句话分开

浏览器报 502 Bad Gateway:Nginx 连不上后端的 PHP-FPM(connect() to unix:/tmp/php-cgi.sock failed),后端进程不在了或者排队满了。

浏览器报 504 Gateway Time-out:连上了,但后端在规定时间内没给答复(upstream timed out),通常是脚本在等数据库、等外部接口。

前者查进程和 pm.max_children,后者查慢查询和远端调用。搞反了就会在错误的地方改一晚上。pm.max_children 该开多大有个简单估算法:可用内存 ÷ 单个 PHP-FPM 进程常驻内存(ps --no-headers -o rss -C php-fpm8.2 | awk '{s+=$1} END {print s/NR/1024" MB"}' 可以量出来)。

顺带一提,打开网站报错时先分清是「DNS 没解析」还是「服务器没响应」:浏览器显示 DNS_PROBE_FINISHED_NXDOMAIN 是域名层的事,报 502/504 才是服务器层的事,两者的排查方向完全相反。

8 个数字的基线表

看什么 命令 正常 该动手了
负载 uptime 1 分钟 load ≤ CPU 核数 持续 > 核数 × 2
CPU 空闲 top 的 id > 60% 长期 < 10%,同时 wa 高
可用内存 free -m 的 available > 总内存 20% < 100 MB 且 swap 在涨
磁盘容量 df -h < 80% > 90%
inode df -i < 80% > 90%,空间够也写不进
磁盘 IO iostat -x 1 %util < 60 %util ≈ 100、await 上百 ms
连接数 ss -s TIME_WAIT 几十到几百 上万且持续增长
内核杀进程 dmesg -T | grep -i oom 无输出 出现 Killed process

查的顺序,比查什么更重要

把上面 8 项按第一条到第二条的顺序走一遍,其实只花了不到两分钟,但能把问题范围从「网站慢」压缩到「磁盘 IO 堵」或者「PHP-FPM 子进程耗尽」这种具体结论。有了结论再动手改配置,改完用同样的 8 个数字复测一次,才算真的修好了。

反过来说,跳过这一步直接改 php.ini、加缓存插件、升级配置,等于闭着眼睛调参数——改完变快了也说不清是为什么,下次换个症状照样抓瞎。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容