服务器变慢时,最常见的误判是凭感觉下结论:网站慢就说是 CPU 不够,数据库卡就说是内存不足。实际上 CPU、内存、磁盘、网络各有各的瓶颈特征,看错方向会导致无效的扩容,钱花了问题还在。比如磁盘 I/O 拥塞时,负载平均值也会飙升,看起来像 CPU 不够,但加核毫无作用。
这篇文章系统介绍 Linux 上查看 CPU、内存、磁盘的常用工具:top、htop、atop、vmstat、free、df、du、iostat、sar、nproc、glances,并解释那些让人困惑的指标含义,比如 us、sy、id、wa、si、st 分别代表什么,为什么内存看起来被吃光了其实还有大把可用,以及磁盘 %util 到多少才算真的到瓶颈。看完你应该能独立判断一台机器到底卡在哪。
先看全局:uptime 与负载
动手之前,先用一条命令建立整体印象:
uptime
# 10:20:31 up 45 days, 3:12, 2 users, load average: 0.85, 1.20, 1.05
nproc
cat /proc/loadavg
负载平均值是三个数字,分别对应最近一分钟、五分钟、十五分钟内处于可运行状态以及不可中断睡眠状态的平均任务数。它不等于 CPU 百分比。四核机器负载到四左右是满载,十六核机器负载到四还很轻松。判断时要和 nproc 给出的逻辑核心数对比。
三个数字的趋势比绝对值更重要:一分钟高、十五分钟低,说明是刚刚起来的瞬时压力;十五分钟也高,说明是持续压力。还要注意,处于 D 状态(不可中断睡眠,通常是等磁盘 I/O)的进程也会计入负载,所以磁盘慢时负载会跟着升高,这是很多人误判的根源。
CPU:top、htop、atop 怎么看
top 是每台机器都有的基础工具,无需安装:
top
顶部第一行是负载,第二行是任务统计,第三行是 CPU 分布,第四五行是内存和交换分区。常用快捷键:P 按 CPU 排序,M 按内存排序,1 展开每个逻辑核心,c 显示完整命令行,H 显示线程,z 彩色显示,q 退出。
第三行那是本文第一个重点:
%Cpu(s): 12.5 us, 4.2 sy, 0.0 ni, 80.1 id, 2.8 wa, 0.0 hi, 0.3 si, 0.1 st
| 字段 | 全称 | 含义 | 持续偏高的常见原因 |
|---|---|---|---|
us |
user | 用户态代码消耗的时间 | 业务计算、加解密、压缩、正则、GC、死循环 |
sy |
system | 内核态消耗的时间 | 系统调用频繁、网络包处理、上下文切换、驱动 |
ni |
nice | 调整过优先级的进程消耗 | 后台任务,一般不用管 |
id |
idle | 空闲时间 | 越高越闲 |
wa |
iowait | CPU 空闲但在等 I/O 完成 | 磁盘慢、存储拥塞、同步写多 |
hi |
hardware irq | 硬件中断处理 | 网卡、磁盘控制器中断 |
si |
software irq | 软中断处理 | 网络收包、软中断集中在某个核心 |
st |
steal | 被宿主机调度走的时间 | 云服务器宿主机争用、超售、配额不足 |
几个实用判断:wa 高说明瓶颈在存储而不是算力,加 CPU 无效;sy 高且上下文切换巨大,常见于连接数过多或频繁小包网络;si 集中在单个核心,可能是网卡队列绑定不均;st 长期超过百分之五到十,说明底层资源被争抢,应保留证据联系服务商,不要凭一次尖峰下结论。
htop 界面更友好,支持鼠标和树状视图:
# RHEL、Rocky、CentOS
sudo dnf install -y epel-release
sudo dnf install -y htop
# Debian、Ubuntu
sudo apt update
sudo apt install -y htop
htop
在 htop 里按 F2 可以配置显示项,F5 切换树状视图,F6 选择排序列,按 / 搜索进程。它适合交互查看,但排障留证还是要用可复制的文本快照。
atop 的优势在于能看到已退出的进程,这对排查半夜挂掉又重启的服务特别有用,而且它内置了磁盘和网络层的视角:
# RHEL、Rocky、CentOS
sudo dnf install -y atop
# Debian、Ubuntu
sudo apt update
sudo apt install -y atop
atop # 实时视图
atop -r # 回放当天历史记录
atop -r /var/log/atop/atop_20261010 # 回放指定日期
atop 按 c 看 CPU,m 看内存,d 看磁盘,n 看网络,t 翻下一个采样点。历史记录由后台的 atop 服务按十分钟间隔采集,默认保留约二十八天,是事后复盘的利器。
CPU 规格与硬件信息
nproc # 逻辑核心数
lscpu # 汇总:架构、核心、线程、频率、缓存、虚拟化类型
cat /proc/cpuinfo # 每个逻辑处理器的详细信息
grep -m1 'model name' /proc/cpuinfo
grep -c 'processor' /proc/cpuinfo
lscpu 里要关注三点:Thread(s) per core 判断是否开了超线程,超线程带来的性能通常只有物理核心的两到三成增益;CPU MHz 在云环境可能显示标称值而非实际睿频;Hypervisor vendor 能确认是不是虚拟机。
按核心看是否均衡:
# 需要 sysstat
mpstat -P ALL 1 5
如果只有一个核心长期接近满载而其他空闲,常见原因是单线程瓶颈、锁竞争或设置了 CPU 亲和性,加核心帮助有限。所有核心都忙则是总体容量问题。
内存:free 与 /proc/meminfo
free -h
输出大致如下:
total used free shared buff/cache available
Mem: 7.7G 2.1G 512M 128M 5.1G 5.2G
Swap: 2.0G 0B 2.0G
这里最容易误解的是 used 和 free。Linux 的设计哲学是空闲内存就是浪费的内存,内核会把空闲内存拿去做页缓存和缓冲区,用来加速文件读写,这部分就是 buff/cache。当应用真正需要内存时,内核会自动回收页缓存,所以 buff/cache 大不是问题,反而是好事。
真正需要关注的是 available,它估算的是在不触发交换的情况下,还能分配给新进程多少内存。判断内存是否紧张,看 available 而不是 free。经验上,available 长期低于总内存的百分之十,或者 Swap 的 used 持续增长,才算真的紧张。
| 字段 | 含义 | 关注点 |
|---|---|---|
total |
总物理内存 | 与业务规模匹配 |
used |
已用,含缓存 | 单独看意义不大 |
free |
完全未用 | 很小属正常 |
shared |
tmpfs、共享内存 | 容器和数据库场景会较大 |
buff/cache |
块缓冲 + 页缓存 | 可被回收,不算占用 |
available |
可供新进程使用 | 判断是否紧张的核心指标 |
Swap used |
已用交换空间 | 持续增长是危险信号 |
更细的内存信息在 /proc/meminfo:
cat /proc/meminfo | head -n 20
grep -E 'MemTotal|MemAvailable|Buffers|Cached|SwapCached|Active|Inactive|Slab' /proc/meminfo
几个补充判断点:SwapCached 大说明有页面被换出又换回来;Slab 异常大可能是内核对象泄漏,常见于 dentry 和 inode 缓存;Dirty 长期很高说明有大量数据等待回写,可能伴随 I/O 抖动。
按进程看内存占用:
ps -eo pid,user,%mem,rss,vsz,comm --sort=-rss | head -n 15
注意区分 RSS 和 VSZ:RSS 是实际占用的物理内存,VSZ 是虚拟地址空间,包含映射但未实际使用的部分。Java 进程的 VSZ 通常远大于 RSS,拿 VSZ 说内存不够是常见误判。
交换分区使用情况:
swapon --show
vmstat 1 5
cat /proc/sys/vm/swappiness
swappiness 默认值六十,值越大越倾向使用交换。数据库服务器常建议降到一到十,减少被换出的概率,但修改前要评估,因为过度压低可能在内存真的紧张时触发 OOM。
磁盘空间:df 与 du
空间不足和性能瓶颈是两回事,先分清再看工具。
df -h # 按挂载点看使用率
df -hi # 看 inode 使用率
df -hT # 显示文件系统类型
注意 df -hi:有时候磁盘还剩很多空间,却报 No space left on device,那通常是 inode 耗尽,常见于小文件极多的场景,比如邮件队列、会话文件、容器镜像层。
找出占空间的大目录:
du -h --max-depth=1 /var 2>/dev/null | sort -hr | head -n 20
du -sh /var/* 2>/dev/null | sort -hr | head
du -ah /data | sort -hr | head -n 30 # 精确到文件
df 显示已删除但被进程占用的空间时会出现矛盾:文件删了但空间没释放。用下面的命令找出这类文件:
lsof +L1
lsof | grep deleted
处理方式不是重启机器,而是让持有句柄的进程重新打开文件,或者用 truncate 把内容截断:
: > /proc/PID/fd/文件描述符 # 需确认后操作
风险提示: 直接清空正在写入的日志文件只是临时缓解,本质问题是日志没有轮转。应配置 logrotate 而不是定期手工删除。
磁盘性能:iostat 与 iotop
# RHEL、Rocky、CentOS
sudo dnf install -y sysstat
# Debian、Ubuntu
sudo apt update
sudo apt install -y sysstat
iostat -x 1 5
iostat -x -d sda 1 5
重点看 Device 段的这几列:
| 字段 | 含义 | 经验参考 |
|---|---|---|
r/s、w/s |
每秒读写请求数 | 机械盘几十到几百,SSD 可达数万 |
rkB/s、wkB/s |
每秒读写字节数 | 与带宽上限对比 |
await |
请求平均等待时间(毫秒),含排队和服务 | SSD 通常低于五毫秒,机械盘十毫秒左右 |
r_await、w_await |
读写分别的等待时间 | 写远高于读可能是 RAID 或写缓存策略 |
%util |
设备处理请求的时间占比 | 接近百分之百基本是饱和信号 |
aqu-sz |
平均请求队列长度 | 持续大于一说明有排队 |
svctm |
已废弃的计算值 | 不要作为判断依据 |
%util 的解读要小心:对于支持并发的 SSD 和多队列设备,%util 接近百分之百不一定代表真正饱和,因为它是时间占比而非吞吐上限。应该结合 await 和 aqu-sz 一起看:如果 await 明显上升、队列变长、业务延迟同步变高,才是真的瓶颈。
机械盘 await 超过二十毫秒、NVMe 超过五到十毫秒,用户通常就能感知到卡顿。这是经验值,具体阈值要结合业务容忍度。
按进程看 I/O:
sudo iotop -o # 只看有 I/O 的进程
sudo iotop -oa # 累计视图
iotop 需要内核开启相关统计选项,某些精简内核或容器环境可能不可用。
综合视图:vmstat 与 sar
vmstat 一条命令同时给出进程、内存、交换、I/O、系统和 CPU:
vmstat 1 10
vmstat -w 1 10 # 宽输出,列对齐更清晰
重点关注:r 列是运行队列长度,长期大于 CPU 核心数说明有排队;b 列是不可中断睡眠的进程数,大于零通常意味着 I/O 阻塞;si、so 是每秒换入换出,持续非零说明内存压力大;cs 是每秒上下文切换,几万以上是正常的,几十万甚至上百万就要找原因;us、sy、id、wa、st 的含义与前面一致。
sar 的价值在于历史回顾,它由 sysstat 的定时任务每十分钟采集一次:
sar -u 1 5 # 实时 CPU
sar -r 1 5 # 内存
sar -b 1 5 # I/O 传输量
sar -d 1 5 # 块设备
sar -q 1 5 # 队列与负载
sar -n DEV 1 5 # 网络接口
sar -u -f /var/log/sa/sa10 # 查看 10 号的历史
sar -u -s 09:00:00 -e 12:00:00 -f /var/log/sa/sa10
RHEL 系历史数据在 /var/log/sa/saNN,Debian、Ubuntu 在 /var/log/sysstat/saNN,NN 是日期。需要确认采集开关已打开,RHEL 系编辑 /etc/sysconfig/sysstat,Debian、Ubuntu 编辑 /etc/default/sysstat 把 ENABLED 改为 true,然后重启 sysstat 服务。
glances 是一个把所有指标集中在一屏的工具,还支持 Web 模式和 API:
# RHEL、Rocky、CentOS
sudo dnf install -y glances
# Debian、Ubuntu
sudo apt update
sudo apt install -y glances
glances
glances -w # 以 Web 方式提供,默认端口 61208
在 glances 里,绿色表示正常,蓝色是提示,紫色是警告,红色是严重。它适合快速巡检,但生产排障仍然建议用 sar、atop 这类能留下历史数据的工具。
一套可复用的排查顺序
遇到机器变慢,建议按下面顺序走,五分钟内能定位到方向:
# 第一步:整体印象
uptime; nproc; free -h; df -h
# 第二步:CPU 分布
top -b -n 1 | head -n 15
# 或
vmstat 1 5
# 第三步:找进程
ps -eo pid,user,stat,%cpu,%mem,etime,args --sort=-%cpu | head -n 15
# 第四步:磁盘是否瓶颈
iostat -x 1 5
# 第五步:历史对比
sar -u -f /var/log/sa/$(date +%d)
判断逻辑是:先看负载与核心数,再看 CPU 各字段分布,如果 wa 高就转去查磁盘,如果 us 高就找进程,如果 st 高就怀疑宿主机。内存不要看 free,看 available 和 si/so。磁盘不要只看 %util,要结合 await 和队列长度。
常见问题
内存显示用了百分之九十,是不是要加内存了?
不一定。先看 available 这一列,如果还有两三 GB 可用,说明大部分是被页缓存占用,是可回收的。只有当 available 长期很低、si/so 持续非零、应用开始报 OOM 时,才需要扩容或优化。
wa 很高但 iostat 看起来没什么压力,怎么回事?
可能是单次采样正好错过了峰值,建议用 iostat -x 1 30 连续采样三十次。也可能是网络文件系统(NFS)或虚拟化存储后端慢,本地 iostat 不体现。还有一种情况是少量进程同步写,量不大但延迟极高。
%util 到百分之百就是磁盘满了?
不是。%util 是时间占比,不等于吞吐上限,也不等于空间占用。空间要看 df -h。判断是否饱和要结合 await、队列长度和业务延迟。
为什么 top 里某个进程 CPU 是百分之二百?
多核 Linux 中,一个逻辑核心满载记为一百,进程占用两个核心就是约二百,属于正常显示方式。用 top -H -p PID 可以看到线程级的占用。
历史数据没采集,事后怎么复盘?
如果没装 sysstat 或 atop,就只能依赖云厂商的监控面板和业务自身指标。建议新机器上线第一件事就是安装并启用 sysstat 和 atop,它们占用极小,却能给事后复盘留下唯一线索。
总结
- 先看
uptime和nproc建立上下文,负载要和核心数对比,三个数值的趋势比单点更重要。 - CPU 要区分
us、sy、wa、si、st,wa高是存储问题,st高是宿主机争用,两者的处理方式完全不同。 - 内存看
available而不是free,buff/cache是可回收的页缓存,占用大是正常且有益的。 - 磁盘分空间和性能两类问题:空间用
df -h加df -hi,性能用iostat -x看await、队列和%util的组合判断。 - 新机器上线就装好
sysstat和atop,把历史数据留下,事后复盘才有依据,而不是靠猜。
企业QQ咨询




