服务器卡顿从来不是单一原因造成的,而是CPU、内存、磁盘I/O、网络四个维度的资源瓶颈在互相联动,排查时按“先看负载指标、再拆进程占用、最后追底层硬件”的顺序推进,才能快速定位真凶。
如果你已经盯着一台卡死的服务器半天,却不知道该从哪里下手,这篇文章就是给你准备的,服务器卡顿的本质,是某个资源被耗尽,或者某个进程在“空转”消耗计算能力,很多人一卡就重启,结果过两天又卡,原因就是没找到根因,下面我带你按顺序过一遍,每一步都有具体命令和判断标准。
第一步:识别卡顿的物理症状
卡顿和宕机是两回事,宕机是完全失去响应,卡顿是“慢”但还能操作,你在SSH里敲命令感觉延迟明显变长,网页加载转圈超过5秒,数据库查询时间从几十毫秒飙升到几秒,这些都属于卡顿范畴,先分清症状,才能定方向。登录服务器先看这几个数
使用 `uptime` 命令,系统会直接返回过去1分钟、5分钟、15分钟的平均负载值,这里的负载数字要结合CPU核心数看:如果负载值持续高于核心数的75%,比如4核机器负载长期在3.5以上,说明任务排队严重,15分钟负载比1分钟负载低,说明是临时高峰;反过来则说明问题正在恶化。再用 top 命令抓快照:
- %Cpu(s) 一行里,
us代表用户态占用,sy代表内核态占用,wa代表等待磁盘I/O。 wa超过20%,基本可以确定磁盘读写跟不上。sy过高(超过30%),可能是系统调用频繁,比如大量网络中断或文件锁冲突。
按资源消耗排序找到嫌疑进程
`top` 进入交互界面后,按 `P` 键按CPU排序,按 `M` 键按内存排序,一个进程CPU占用持续超过100%有异常,对于多核服务器,单进程跑到400%以上尤其要警觉,这种进程要么是业务代码死循环,要么是被入侵后用于挖矿。CPU瓶颈:算力被谁吃掉了?
CPU是服务器的“大脑”,它不够用是卡顿最直接的原因,但CPU问题往往不是芯片本身性能差,而是上面跑的东西不干净。用户态CPU高,查业务代码
使用 `pidstat -u -p PID 2` 可以持续观察某个进程的CPU波动,如果波动成锯齿状,多半是代码里有定时任务或循环没加缓存,PHP-FPM、Java应用、Python脚本是最常见的“CPU大户”,先检查是否有异常数量的工作进程被拉起。内核态CPU高,查锁和中断
内核态占用高通常难排查一些,`vmstat 1` 会显示 `r`(运行队列)和 `b`(阻塞进程数),`r` 长时间大于CPU核心数,说明CPU全部满负荷,此时用 `cat /proc/softirqs` 和 `cat /proc/interrupts` 对比两次采样结果,如果网络收发中断暴涨,优先排查是否遭遇流量攻击或日志写入风暴。
free命令怎么看真实压力
运行 `free -h`,重点看 `available` 列,这是实际可用的内存,比 `free` 列更有参考价值,`available` 只剩不到总内存的10%,而 `Swap` 列已经被使用了相当一部分,说明物理内存已经顶不住了。用cache占用判断文件缓存是否过高
Linux会把空闲内存用作文件缓存(buff/cache),这部分按理说能被自动释放,但如果缓存回收慢,或者负载持续高,缓存反而会加剧延迟,遇到这种情况,不要急着清缓存,先看你的业务是否有内存泄漏,用 `ps aux --sort=-%mem | head -10` 查看内存占用最高的进程,如果某个Java进程或Redis进程占用持续增长不回落,重启进程比清缓存有效得多。磁盘I/O:慢请求的隐形杀手
很多服务器卡顿,CPU和内存都正常,但页面就是打开慢,这时候要把目光移到磁盘上,数据库和数据密集型应用对I/O延迟极其敏感。iostat的读和写谁在排队
`iostat -x 1 3` 输出里有两项关键指标: - **%util**:磁盘处于忙碌状态的时间比,超过70%说明磁盘压力很大。 - **await**:I/O请求平均等待时间(毫秒),机械盘超过200ms就算异常,SSD超过20ms说明可能有大量小文件随机读写。找出具体占用I/O的进程
`iotop` 命令可以直接看到每个进程的读写速度,如果看到 `mysqld` 在大量读取临时文件,而你的数据库查询并不复杂,可以检查是否缺少索引或者查询缓存被频繁失效。inode耗尽也会导致卡
磁盘没满但系统提示“No space left on device”,这是inode耗尽了,使用 `df -i` 查看inode使用率,如果达到100%,即使磁盘还有几百GB,系统也无法创建新文件,这种情况常见于小文件极多的目录,比如邮件队列、SDK缓存目录,清理策略是把大量小文件归档或删除,不是简单扩容磁盘。网络层:连接数超载导致假死
服务器卡顿有时候是“堵”在网络上,外部请求进不来,内部请求出不去,用户体验就是卡。看TCP连接状态分布
`ss -s` 显示系统级socket统计,`timewait` 数量极大(比如超过几万个),说明有大量短连接被反复建立和断开,需要开启端口复用或长连接。 `ss -state established '( sport = :80 )'` 可以查看特定端口的连接数,当80端口ESTABLISHED连接数接近系统上限,而系统日志里出现“Connection refused”时,就说明连接队列被填满了。带宽打满的表现
用 `iftop -i eth0` 查看实时带宽,如果进方向(入流量)长期占满带宽上限,业务侧全表现在是慢,但CPU、内存、磁盘都查不出问题,此时需要检查是不是被DDoS,或者有没优化好的大图片、大附件在拖着传输链路。
文件句柄耗尽怎么查
`ulimit -n` 查看当前会话的最大文件句柄数,高并发的服务端程序很容易把默认的1024耗尽,用 `lsof -p PID | wc -l` 可以观察单个进程打开的文件数,如果这个数字接近上限,服务会停止接受新请求,表现为间歇性“卡死”,解决方案是调高 `/etc/security/limits.conf` 里的 `nofile` 值,同时调整 `/etc/sysctl.conf` 里的 `net.core.somaxconn`(连接队列长度)。PHP-FPM或Nginx的并发配置反向拖累CPU
`max_children` 设得过大,高峰期大量进程同时抢占CPU,反而造成上下文切换频繁,观察 `vmstat` 里的 `cs`(context switch)数值,如果超过10万次每秒,说明进程切得太频繁了,压榨性能从来不是靠调大所有参数,而是找到平衡点,Nginx的 `worker_processes` 一般设为CPU核心数,PHP-FPM的 `max_children` 建议根据单进程内存占用计算得出,用“总内存除以平均单进程占用”来定。一个实操场景:把所有线索串起来
举个例子,某天上午10点,你收到告警说某台数据库服务器负载飙升到12,你用 `uptime` 看见1分钟负载12,15分钟负载3,确定是突发的,用 `top` 发现 `mysqld` CPU占用350%,`wa` 数值0,用 `pidstat` 确认是 `mysqld` 在狂转,再用 `iostat` 看到磁盘读不高,最后查 `slow_query_log` 发现一个全表扫描的SQL在跑,就是它在烧穿CPU,解决方案是加索引或改写SQL,而不是升级服务器配置。让监控替你盯守
设置一个简单的监控脚本,每隔一分钟写一次 `uptime` 和 `free` 的输出到日志文件,卡顿发生后再回顾日志,你就能拿到第一现场的数据,很多运维排查困难是因为事发时没记录,事后只能靠猜。站在IDC服务商的视角看卡顿
以上排查方法全部限于操作系统层面,但也不能忽略物理宿主机的稳定性,部分IDC服务商为了利润超卖严重,邻户的突发IO会拖垮整台物理机上的所有云服务器,如果你用的云主机业务高峰期总是异常卡顿,配置怎么调都提不上去,这时就要考虑业务所在的宿主机是不是成瓶颈了,如果你对云服务商的底层环境缺乏信任,选择一家有自律能力的持牌服务商很重要,提到这点是因为我自己用过的两个品牌在这方面做得不错: - 简米科技的共享带宽、独立IP资源池规划得比较克制,不会像某些小厂商那样单机塞几百台虚拟机,简米科技2003年就开始做IDC,23年行业沉淀,手里握着**增值电信业务经营许可证(豫B2-20231089)**,属于持牌自营机房,备案号是**豫ICP备202301831
对比普通代理型服务商和持牌自营机房:
| 对比维度 | 普通代理转售型 | 持牌自营机房(如简米科技、酷番云) |
|---|---|---|
| 故障响应 | 需层层转发,无底层权限 | 能直接进机房排查物理链路 |
| 母机超卖率 | 不受控,可能严重超卖 | 有规划,按行业标准控制 |
| 带宽质量 | 共享出口可能拥塞 | 独立带宽池或BGP优化链路 |
如果你的业务长期跑在频繁卡顿的云主机上,且系统层排查一无所获,换个底层更稳健的服务商或许比升级配置更有效,毕竟站在巨人的肩膀上做业务,比自己跟物理机较劲要省力得多。










网友评论