Linux服务器性能排查常用命令大全:CPU内存磁盘网络一次看懂
半夜两点被叫起来处理一台业务机响应变慢,登上去第一件事肯定不是重启服务,而是把 CPU、内存、进程、磁盘 IO、网口流量这几个维度挨个扫一遍。这套 动作做过几十次之后你会发现,Linux 系统里真正高频用到的信息查看命令其实就那二十来个,剩下的都是它们的变体或者祖宗辈的老写法。这篇东西就是把这些命令按"看什么、怎么看、看到数值之后怎么判断"的顺序整理出来,覆盖 CPU、内存、进程、网口、磁盘、硬件这几大类,尽量把每个参数背后的含义和常见的误判点讲清楚。适合刚接手 Linux 服务器的新人,也适合平时主要写业务代码、偶尔要自己登机器排查问题的开发同学。命令本身不难记,难的是看到一堆数字之后知道哪个是异常、哪个只是正常波动,这才是真功夫。
1. 先想清楚要看什么:系统信息排查的分层思路
很多人一上来就 top ,然后盯着跳动的数字发呆,其实是没有先建立分类的概念。系统信息大致可以分成三层:静态硬件层(这台机器到底是什么配置)、动态资源层(CPU、内存、IO、网络的实时消耗)、进程与连接层(具体是谁在消耗)。这三层的查看命令、判读标准、采样方式都不一样,混在一起看只会越看越乱。
1.1 静态硬件层和动态资源层的区分
静态硬件层回答的是"这台机器有多少家底",典型命令有 lscpu 、 lsblk 、 lspci 、 dmidecode 、 free -h 的 total 列。这类信息基本不会变,除非你热插拔硬盘或者改配置。拿到一台陌生机器,我习惯先把这一层过一遍,记下核数、内存总量、磁盘数量与类型、网卡速率,后面所有"是否异常"的判断都要跟这些基准值对比。
动态资源层回答的是"现在消耗了多少", top 、 vmstat 、 iostat 、 sar 都属于这一类。它们的核心特点是需要采样,单次输出几乎没有意义,必须看趋势。比如 vmstat 1 5 是每秒采一次共采五次, iostat -x 1 是持续输出,看的就是连续性。
进程与连接层则是把上面的消耗定位到具体对象:哪个 PID 吃了 CPU,哪个端口被谁占着,哪个进程打开了这个已删除的大文件。 ps 、 ss 、 lsof 、 fuser 是主力。
提示:排查顺序建议从静态层确认基准,再到动态层找异常维度,最后到进程层定位元凶。反过来直接看 top ,很容易被瞬时峰值带偏。
1.2 采样方式选错,结论就全错
这是新手最容易踩的坑。CPU 使用率如果只看 top 刷新出来的那一瞬间,很可能看到 90% 就慌了,实际上那只是某个批处理任务刚起来的瞬时冲高。正确的做法是看一段时间内的平均值,比如 top 里按 1 切到每核视图观察几秒,或者直接用 vmstat 1 10 拿十秒的数据。
磁盘 IO 同理。 iostat 第一次输出的那一行通常是从开机到现在的累计平均值,不是当前值,真正要看的是第二次及以后的采样行。这个细节官方文档里写得比较隐晦,但实际排查中如果拿第一行当当前值,结论会完全跑偏。
网络流量也一样, sar -n DEV 1 5 采五次,看的是每秒的包量和字节数变化,单看 /proc/net/dev 的累计计数只能算总账。
1.3 单位换算是最容易翻车的地方
free 默认按 KB 输出, df -h 才是人类可读, iostat 的 kB_read/s 是每秒千字节, ethtool 报的是 Mb/s 而 sar 报的是 kB/s,中间差了一个 8 倍的换算。我自己就干过把网卡 1000Mb/s 当成 1000MB/s 的事,然后算带宽利用率算出了个荒唐结果。
把这几个换算关系背下来会省很多事:1 字节 = 8 比特,1 MB = 1024 KB,网卡速率标称的是比特。所以一块千兆网卡的理论极限大约是 125 MB/s, sar 里看到 110000 kB/s 就已经接近打满了。
2. CPU 信息:从型号识别到实时负载判读
CPU 相关的命令分两拨,一拨认硬件(这是什么 CPU、几个核几个线程、支持什么指令集),一拨看负载(现在忙不忙、谁在忙)。这两拨不要混着用, lscpu 看不出当前负载, top 也看不出你这颗 U 有没有 AVX 指令集。
2.1 lscpu 和 /proc/cpuinfo 该用哪个
lscpu 是首选,输出整齐,直接告诉你架构、CPU 型号、核心数、线程数、缓存层级、NUMA 节点。几个关键字段需要看懂:
CPU(s):逻辑 CPU 总数,也就是top里按1能看到的条数Thread(s) per core:每核线程数,2 表示开了超线程Core(s) per socket:每颗物理 CPU 的核心数Socket(s):物理 CPU 颗数
它们的关系是 CPU(s) = Socket(s) × Core(s) per socket × Thread(s) per core 。一台双路、每路 16 核、开了超线程的机器, CPU(s) 就是 64。这个数字决定了后面 load average 该怎么判读,非常重要。
cat /proc/cpuinfo 信息更原始更全,但一股脑输出几百行,人眼很难看。它的价值在于脚本化——比如批量查所有机器是否支持某个指令集时, grep -o 'avx512' /proc/cpuinfo | head -1 就很方便。日常人工查看还是 lscpu 舒服。
lscpu | grep -E 'Model name|Socket|Core|Thread|NUMA'
2.2 load average 到底怎么看
uptime 会输出三个数字,分别是过去 1 分钟、5 分钟、15 分钟的平均负载。很多人以为它表示 CPU 使用率,其实不是——它统计的是运行队列中可运行和不可中断状态的进程数,包含了等待 IO 的进程。所以一台 CPU 很闲但磁盘卡死的机器,load 一样会飙到很高。
判读标准是拿它跟逻辑 CPU 核数比。64 核的机器 load 到 30 都算轻松,4 核的机器 load 到 8 就明显过载了。我自己的经验阈值是:load / 核数 小于 0.7 属于健康,0.7 到 1.0 需要关注,超过 1.0 且持续超过 5 分钟就要介入看了。
三个数字的走势也能说明问题。如果 1 分钟很高、15 分钟很低,说明是刚起来的突发流量;如果三个都很高且接近,说明是持续性压力,这种通常更难处理,得从根上找原因。
2.3 定位高 CPU 进程的组合拳
top 是最直观的,进去之后几个操作必须会:按 P 按 CPU 排序,按 M 按内存排序,按 1 展开每核视图,按 H 显示线程,按 c 显示完整命令行。这几个按键记住之后, top 能解决八成问题。
但 top 有个毛病:默认刷新太快,跳来跳去不好截图也不好观察。我更喜欢在脚本或者长期观察场景下用 ps 排序:
ps -eo pid,ppid,user,%cpu,%mem,stat,etime,cmd --sort=-%cpu | head -15
这里 etime 是进程运行时长,很有用。如果一个进程 CPU 高而且运行了很久,那大概率是慢查询或者死循环;如果刚起来 CPU 就高,可能是正常的初始化或编译任务。 stat 列里出现 D 状态要特别留意,那是不可中断睡眠,通常卡在 IO 上。
再深入一点可以用 pidstat ,它能按进程甚至按线程持续采样:
pidstat -u 1 5 # 按进程看 CPU pidstat -t -p 12345 1 5 # 按线程看指定进程
pidstat -t 这个用法在排查 Java 应用时特别好使,因为 JVM 是一个大进程, top 只能看到整体占用, pidstat -t 能直接看到是哪个线程在烧 CPU,拿着线程 ID 转成十六进制再去 jstack 里搜,一抓一个准。
2.4 每核分布不均怎么办
有时候整体 CPU 使用率不高,但业务就是慢。这种情况要怀疑是不是单线程瓶颈——程序只跑在一个核上,那个核 100%,其他核全闲着, top 里的整体数字只有 1/64,看起来一点都不高。
检查方法是在 top 里按 1 展开每核视图,看是否有单核长期接近 100%。 mpstat -P ALL 1 也能达到同样效果,而且输出更适合脚本处理:
mpstat -P ALL 1 3
如果确认是单核打满,方向就是找程序里的单线程瓶颈,或者看能不能通过多进程、多线程模型打散。也有例外情况,比如某些网络中断处理会绑定到固定核上,这时候可能是网卡中断分配不均,需要调整 /proc/irq/*/smp_affinity ,这个属于进阶操作,改之前一定要确认清楚。
注意: %wa (IO 等待)也算在 CPU 的 idle 之外,如果 top 里看到 wa 很高,别急着重启 CPU 相关服务,问题八成在磁盘或网络存储上。
3. 内存查看:free 的输出得会翻译
内存这块的坑比 CPU 还多,因为 free 的输出列名会让第一次看的人误解。最典型的就是看到 free 只剩几百 MB 就以为内存要爆了,实际上 Linux 会把大量空闲内存拿去做文件缓存,需要的时候随时能回收。
3.1 free -h 每一列的真实含义
假设输出长这样:
total used free shared buff/cache available
Mem: 31Gi 8.2Gi 1.1Gi 412Mi 22Gi 22Gi
Swap: 2.0Gi 0B 2.0Gi
total 是物理内存总量。 used 是已使用,注意它包含了部分已被应用占用的缓存。 free 是完全空闲的,也就是真的一点都没被用到的内存,这个数字小不代表有问题。 buff/cache 是内核用于块设备缓存和文件系统缓存的部分,这部分是"借"给内核用的,应用需要时可以快速释放。
关键看 available 。这一列是内核估算的"新应用还能申请到多少内存",它把可回收的 cache 也算进去了。真正判断内存是否紧张,看 available 是不是还很充裕,而不是看 free 。
很多从 Windows 转过来的同学会觉得缓存占了 22G 很浪费,其实这正是 Linux 内存管理的效率体现。反复读同一批文件时命中缓存,速度比读磁盘快好几个数量级。
3.2 buff/cache 怎么手工释放
有时候确实需要手工清缓存,比如做内存基准测试要排除缓存干扰,或者某些老程序对内存可用量的判断有 bug。命令是:
sync # 先把脏页刷盘,必须做 echo 3 > /proc/sys/vm/drop_caches
echo 3 表示同时释放页缓存、目录项和 inode 缓存。 echo 1 只释放页缓存, echo 2 只释放 dentry 和 inode。
注意:这个操作本身代价不小,清完之后所有后续读文件都得走磁盘,可能造成短时间的 IO 峰值。生产环境除非必要别乱敲。
想更细地看内存构成,读 /proc/meminfo 更全,里面 MemTotal 、 MemFree 、 MemAvailable 、 Cached 、 Buffers 、 Dirty 、 Slab 都是常用字段。其中 Dirty 是还没写回磁盘的脏页大小,如果这个数字长期偏高且不下降,说明写的速度超过了磁盘的吞吐能力,迟早要出问题。
3.3 内存泄漏的排查手法
进程内存持续增长不释放,是最让人头疼的问题之一。定位的基本流程是:先找到嫌疑进程,再看它的内存构成,最后确认是堆还是栈或者 mmap 的问题。
按内存排序和按 CPU 排序其实命令一样,只是排序字段换一下:
ps -eo pid,user,%mem,rss,vsz,cmd --sort=-rss | head -15
RSS 是常驻内存,也就是真正占着物理内存的部分; VSZ 是虚拟内存总量,包含了还没实际分配的部分。看内存泄漏主要盯 RSS , VSZ 大不一定有问题。
确定了 PID 之后, pmap -x PID 能列出这个进程的内存映射明细, cat /proc/PID/smaps 信息更全但更长。这两个工具在追查"内存到底去哪了"的时候能给出地址段的分布,配合 gdb 或者语言自带的 dump 工具可以进一步定位。
smem 这个工具值得装一下,它和 ps 最大的区别是会处理共享内存的重复计算问题。多个进程共同映射同一个共享库时, ps 会把库的大小在每个进程里都算一遍,加起来远超物理内存,容易吓人。 smem 用 PSS 来处理这件事,统计更接近真实。
3.4 swap 和 OOM 的线索在哪
free 输出里的 Swap 行别忽略了。swap 使用量持续增长通常意味着物理内存不够,系统开始往磁盘上倒腾。这时候机器的表现是响应变慢但 CPU 不一定高,因为瓶颈在磁盘 IO 上。
vmstat 1 5
看 si 和 so 两列,分别是每秒从 swap 读入和写入的量。如果这两个值长期非零,基本可以确认内存不足。短期偶尔跳一下没事,长期持续就要考虑加内存或者优化程序了。
如果进程被杀掉了,去 dmesg 里找 OOM 记录:
dmesg -T | grep -i -E 'oom|killed process'
-T 参数会把时间戳转成人类可读的格式,方便跟日志对时间。OOM killer 触发时会打印被选中进程的 PID、内存占用、评分,这些信息对于分析"为什么偏偏杀了我这个进程"很有帮助。OOM 评分大致和进程占用的内存成正比,但可以用 /proc/PID/oom_score_adj 调整,这个属于调优范畴了。
4. 进程与连接:ps、top、ss、lsof 的实战搭配
进程这一块命令最多,但常用的就那么几个组合。核心思路是:先用 ps 或者 top 找到嫌疑进程,再用 ss 或者 lsof 看它占着哪些资源,最后回到 ps 确认它的父子关系和启动参数。
4.1 ps 的两种风格别搞混
ps 有 BSD 风格和 UNIX 风格两套参数体系,新手经常混用导致参数被误解析。BSD 风格不加横线, ps aux ;UNIX 风格加横线, ps -ef 。两者输出的内容差不多,只是列名和排序不同。
ps aux 的列是 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND , ps -ef 的列是 UID PID PPID C STIME TTY TIME CMD 。
我个人的习惯是:需要快速看 CPU 和内存占比用 aux ,需要看父子进程关系用 -ef 。两者都用 grep 过滤时记得排除自己那条 grep 进程:
ps -ef | grep nginx | grep -v grep
或者更优雅的写法:
pgrep -a nginx
pgrep 和 pkill 是一对,前者按名字找 PID,后者按名字杀进程。 pkill 用之前一定要用 pgrep 确认命中范围,不然很容易误杀。
pstree -p 能直观地把进程树画出来,排查"某个服务被谁拉起来的"这种问题时特别好用,因为它把父子关系用缩进的方式呈现了,一眼就能看出层级。
4.2 top 交互操作的几个隐藏技能
top 进去之后按 f 可以自定义显示哪些列,按 o 可以设置排序字段,按 k 可以直接杀进程,按 u 只看指定用户,按 z 开彩色显示。这些功能知道的人不多,但用熟了效率提升明显。
top -b -n 1 是批处理模式输出一次就退出,适合写进脚本或者重定向到文件里。想抓某个时间点的快照做对比,这个用法比截图靠谱。
top -H -p PID 可以只显示指定进程的线程,和前面 pidstat -t 效果类似,但交互性更好。
还有一个容易被忽略的: top 输出开头那几行是全局信息, load average 、 Tasks 、 %Cpu(s) 、 MiB Mem 、 MiB Swap 都在这几行里。很多人只看下面的进程列表,其实上面这几行才是第一判断依据。特别是 Tasks 那行的 running 、 sleeping 、 zombie 数字,如果 zombie 不为零且持续增长,说明有父进程没有正确回收子进程,需要查代码。
提示:僵尸进程本身不占 CPU 和内存,但会占用 PID 表项。如果数量持续增长到几万,PID 会被耗尽,新进程无法创建。解决方法通常是找到父进程重启它,或者修复代码里的 wait 逻辑。
4.3 端口和进程的对应关系
netstat 是老牌工具,但已经被 ss 取代了。 ss 速度更快,尤其是在连接数很多的时候,因为它是直接从内核空间取数据,而 netstat 要遍历 /proc 。
常用组合:
ss -tulnp # 看所有监听中的 TCP 和 UDP 端口 ss -tan state established | head -20 # 看已建立的连接 ss -s # 看连接数汇总统计
参数含义: -t TCP, -u UDP, -l 只看监听, -n 不做域名解析(重要,不然会很慢), -p 显示进程,需要 root 权限。
如果想知道某个端口被谁占了,除了 ss -tulnp | grep :8080 ,还可以用 lsof -i :8080 。 lsof 的视角是"进程打开了哪些文件",而 socket 在 Linux 里也是文件,所以它能从进程的角度反向查。
fuser -n tcp 8080 是另一个思路,直接告诉你是哪个 PID,适合写脚本时用。
4.4 lsof 的几种典型用法
lsof 全称是 list open files,功能极其强大,但输出也极其冗长,必须配合过滤条件用。
查某个进程打开了哪些文件:
lsof -p 12345 | head -30
查某个目录被谁占用(比如卸载文件系统时提示 busy):
lsof +D /mnt/data
查某个文件被谁打开:
lsof /var/log/app.log
这个命令有个实际价值极大的用法:删除大文件后磁盘空间没释放。原因是文件被某个进程还持有句柄, rm 只是删掉了目录项,inode 还在。这时候用 lsof | grep deleted 就能找到是哪个进程还挂着这个文件,重启对应进程或者让它重新打开日志文件,空间就能回收。
lsof -n | grep deleted | awk '{print $1,$2,$7,$9}' | sort -k3 -n -r | head
这个组合会按文件大小倒序列出所有已删除但仍被占用的文件,非常实用。
5. 磁盘与文件系统:容量、inode、IO 三条独立线
磁盘问题是最容易引起"服务假死"的,因为磁盘满了之后很多程序写日志失败就卡住了,表现是服务无响应但 CPU 和内存都很正常。所以磁盘检查要养成习惯,至少把容量和 inode 两条线都看一遍。
5.1 df 和 du 的配合方式
df -h # 按挂载点看容量 df -i # 按挂载点看 inode 使用率
df -h 的输出里重点看 Use% 那一列,超过 80% 就该关注了,超过 90% 需要立即处理。注意有些文件系统比如 /dev/shm 是内存文件系统,它的大小跟你物理内存有关,不是真的磁盘。
发现某个分区快满了,下一步是用 du 找大目录:
du -sh /* 2>/dev/null | sort -hr | head -10
-s 是汇总, -h 是人类可读,配合 sort -hr 按大小倒序。找到最大的那个目录之后,一层层往下钻,直到定位到具体的大文件。这个过程可以写成一个循环脚本,不过手工钻个三四层一般也够了。
du 有个坑:它会跟随符号链接(不加 -x 的情况下可能跨越文件系统),而且遍历大量小文件时非常慢。如果目录里文件数量特别多(十万级以上), du 可能需要几分钟,这时候要有耐心,或者用 ncdu 这种交互式工具,体验好很多。
5.2 inode 耗尽怎么发现和处理
这是最隐蔽的磁盘问题之一。 df -h 显示还有很多空间,但程序就是报 "No space left on device"。原因通常是 inode 用完了。
inode 是文件系统给每个文件分配的元数据结构,包含权限、时间戳、数据块指针等信息。每个文件(包括空文件)至少占一个 inode。如果某个目录下堆积了海量的小文件,比如 session 文件、临时文件、邮件队列,inode 就可能先于容量耗尽。
df -i
IUse% 那一列到 100% 就是这个问题了。处理方式是找到小文件最多的目录,通常是 /var/spool 、 /tmp 或者某个应用的缓存目录:
find /var/spool -type f | wc -l # 统计文件数 find /var/spool -type f -mtime +7 -delete # 删除 7 天前的文件
注意: find -delete 一定要先加 -print 空跑一遍确认命中的文件范围,确认无误再改成 -delete 。这个命令误删的案例太多了。
治本的办法还是从源头控制,比如限制日志目录的文件数、给临时文件加自动清理、调整应用的文件命名策略避免碎片化。
5.3 IO 性能怎么看
容量不紧张但 IO 慢,也是很常见的场景。 iostat 是主力工具:
iostat -x 1 5
关注这几列: %util 表示设备繁忙程度,接近 100% 说明磁盘被打满了; await 是平均每次 IO 的等待时间,单位毫秒,机械盘正常在 10ms 以内,SSD 应该在 1ms 以内,超过这个量级说明有瓶颈; aqu-sz 是平均队列长度,持续大于 1 说明有排队。
第一次输出的那一行通常是开机以来的平均值,从第二次开始才是当前采样值,这个前面提过,一定要记住。
iotop 是另一个视角,从进程角度看谁在读写磁盘:
iotop -o -P # 只看有 IO 的进程,-P 显示进程而不是线程(新版本才有)
iotop 需要 root 权限,而且在 IO 压力大的时候自身的开销也不小,不适合长期开着。
如果是网络存储(NFS、iSCSI),IO 的表现会更复杂, await 可能包含网络延迟。这时候最好同时在存储端和客户端两边看,能快速判断瓶颈在哪一侧。
5.4 磁盘硬件信息
lsblk 用树状结构展示块设备,一眼能看出哪块盘分了哪些区,哪些盘做了 RAID 或者 LVM:
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL
-o 指定输出列, MODEL 能显示磁盘型号,排查时确认是不是某批有问题的盘很管用。
blkid 显示每个块设备的 UUID 和文件系统类型,改 /etc/fstab 时经常要用到 UUID,用这个命令取。
如果是物理机, smartctl -a /dev/sda 能读到磁盘的健康状态、通电时间、坏道计数等。重点关注 Reallocated_Sector_Ct 、 Current_Pending_Sector 、 Media_Wearout_Indicator (SSD)这几个值,非零或者持续增长就要考虑换盘了。这个命令需要装 smartmontools 包。
smartctl -H /dev/sda # 快速看健康状态 smartctl -a /dev/sda # 完整信息
5.5 磁盘满了导致进程卡死的排查顺序
这个场景值得单独说,因为它太常见了。现象是服务无响应,但 top 看 CPU 内存都正常, ps 看进程还在。排查顺序我一般是这样:
df -h看容量df -i看 inode- 都正常的话看
dmesg有没有 IO 错误 - 再看
iostat -x 1 5是不是 IO 打满 - 如果有挂载的网络存储,检查网络连通性和挂载点是否还在
第 5 步容易被忽略。有时候 NFS 服务端挂了,客户端进程访问挂载点时会进入不可中断睡眠( D 状态), ps 里能看到,但 kill -9 杀不掉。这种情况只能等网络恢复或者重启机器。
6. 网口与硬件:从 ifconfig 到 dmidecode
网络和硬件这两块平时看得少,但出问题的时候信息量很大。网络重点是看连通性、速率、错误计数;硬件重点是看清单、温度、运行状态。
6.1 网卡状态和流量
ip addr 已经全面取代 ifconfig ,输出更规整,功能也更全:
ip addr show # 看所有网卡和 IP ip -s link show eth0 # 看指定网卡的收发统计
ip -s link 的输出里有 RX errors 、 TX errors 、 dropped 这几列,持续增长说明有物理层问题,可能是网线、光模块或者交换机端口的问题。
ethtool 看的是网卡的物理层信息:
ethtool eth0
重点看 Speed (协商速率,应该是 1000Mb/s 或者 10000Mb/s)、 Duplex (应该是 Full)、 Link detected (应该是 yes)。如果协商成了半双工或者 100Mb/s,说明网线或者对端设备有问题,即使链路是通的,性能也会差很多。
看实时速率用 sar :
sar -n DEV 1 5
rxkB/s 和 txkB/s 是每秒的读写量,单位是千字节。换算成带宽利用率的话,千兆网卡对应 125000 kB/s 的极限。 rxpck/s 是每秒包数,如果这个数字特别高但字节数不高,说明都是小包,可能存在小包攻击或者应用设计问题。
6.2 硬件清单三大件
lspci 列出所有 PCI 设备,主要用来看显卡、网卡、RAID 卡、HBA 卡这些:
lspci | grep -i -E 'ethernet|raid|vga'
lsusb 列 USB 设备,服务器上用得少,但排查 U 盘、加密狗这类设备时有用。
dmidecode 是最全面的硬件信息工具,能读 BIOS、主板、内存条、CPU 的详细信息。需要 root 权限。
dmidecode -t memory # 内存条型号、容量、速率、插槽 dmidecode -t system # 整机型号和序列号 dmidecode -t bios # BIOS 版本
排查内存故障时, dmidecode -t memory 能看到每条内存的插槽位置和状态,如果某条报 Unknown 或者容量不对,可能就是坏了或者没插紧。这个在报修的时候能提供关键信息。
提示: dmidecode 的 -t 参数后面接类型编号或者类型名都行, -t 17 就是 memory device, -t 16 是 physical memory array,两者的区别是前者是单条,后者是整个内存阵列。
6.3 温度和电源
物理服务器温度异常会触发降频,表现是 CPU 明明不满但性能差。 sensors 命令能读各类温度传感器,需要装 lm-sensors 包:
sensors
输出里会有 CPU 核心温度、主板温度、风扇转速。CPU 核心正常在 40 到 70 度之间,持续超过 85 度就要检查散热了。风扇转速字段如果显示 0 或者 N/A,可能是传感器不认,也可能是风扇真的停了,需要开机箱确认。
ipmitool 是服务器带外管理的利器,能读到更全面的状态:
ipmitool sensor list # 所有传感器 ipmitool sdr type Temperature # 只看温度
这个命令走的是 BMC,需要配置好带外网络。优点是即使系统挂了也能读到硬件状态,做无人值守机房巡检特别好用。
6.4 系统整体信息一网打尽
最后补几个通用命令,第一次登上一台机器时习惯性敲一遍,能快速建立整体印象:
uname -a # 内核版本、架构、主机名 hostnamectl # 系统版本、内核、架构、虚拟化类型 cat /etc/os-release # 发行版信息 uptime # 开机时长和负载 who -b # 上次启动时间 last reboot | head # 重启历史
hostnamectl 的输出里会明确写出 Virtualization: kvm 或者 vmware 之类,一眼就能分辨是物理机还是虚拟机,这个在很多场景下很重要。如果是容器环境, cat /proc/1/cgroup 或者 ls /.dockerenv 能判断是不是跑在容器里。
dmesg -T 是排查硬件和内核问题的第一手资料,启动过程的硬件识别、驱动加载、错误报警都在这。出了问题先看这个,比瞎猜快得多。 dmesg -T | tail -50 看最近的, dmesg -T | grep -i error 抓错误。
7. 常见问题速查和踩坑记录
命令记熟了不代表会排查,真正的差距在于遇到现象时的判断速度和方向感。这一章把前面提到的判读标准汇总成表,再单独说几个容易误判的场景。
7.1 系统信息命令速查表
| 关注维度 | 首选命令 | 关键列/字段 | 异常判据 |
|---|---|---|---|
| CPU 全景 | lscpu | CPU(s)、Socket、NUMA | 与预期配置不符 |
| CPU 负载 | uptime / top | load average | load / 核数 > 1.0 |
| CPU 分核 | mpstat -P ALL 1 | %usr、%sys、%iowait | 单核长期 100% |
| 内存概览 | free -h | available | available 接近 0 |
| 内存明细 | cat /proc/meminfo | Dirty、Slab | Dirty 长期不降 |
| swap 活动 | vmstat 1 | si、so | 持续非零 |
| 内存泄漏 | ps -eo rss / pmap | RSS 增长趋势 | 持续单调增长 |
| 进程排序 | ps --sort=-%cpu | %cpu、etime、stat | D 状态长期存在 |
| 线程级 CPU | pidstat -t | 单线程 %CPU | 某个线程持续高 |
| 端口占用 | ss -tulnp | LISTEN、进程名 | 端口与预期不符 |
| 已删除文件 | lsof | grep deleted | SIZE、PID | 占用大量空间 |
| 磁盘容量 | df -h | Use% | > 90% |
| inode | df -i | IUse% | 100% |
| 目录大小 | du -sh * | 排序结果 | 异常大目录 |
| 磁盘 IO | iostat -x 1 | %util、await | %util 接近 100 |
| 进程 IO | iotop -o | DISK READ/WRITE | 单进程持续高 |
| 块设备 | lsblk | TYPE、MOUNTPOINT | 挂载关系异常 |
| 磁盘健康 | smartctl -H | SMART overall | FAILED 或计数增长 |
| 网卡速率 | ethtool eth0 | Speed、Duplex | 低于预期 |
| 网络流量 | sar -n DEV 1 | rxkB/s、txkB/s | 接近理论极限 |
| 网卡错误 | ip -s link | errors、dropped | 持续增长 |
| 温度 | sensors | Core temp | > 85 度 |
| 内核日志 | dmesg -T | error、oom | 出现 OOM 或 IO error |
这张表可以打印出来贴在工位上,遇到问题先扫一眼找到对应命令,比凭记忆瞎敲效率高得多。
7.2 几个容易误判的场景
第一个是缓存占内存。前面说过了, free 那列小不代表缺内存,看 available 。新手看到 buff/cache 占 20 多 G 就急着清缓存,纯属折腾。
第二个是 load 高但 CPU 不高。这种情况八成是 IO 等待,去看 %wa 和 iostat 。load average 统计的是运行队列长度,包含不可中断睡眠的进程,磁盘卡住的进程也算在里面。
第三个是磁盘有空间但写不进去。先查 inode,再查是不是文件被删了但句柄没释放。两个都用 df -i 和 lsof | grep deleted 就能覆盖。
第四个是端口明明没被占但启动报 address already in use。可能是 TIME_WAIT 状态的连接, ss -tan | grep TIME-WAIT | wc -l 看数量。TIME_WAIT 是正常的 TCP 状态,但如果数量特别大(几万),可能需要调整内核参数或者让应用复用连接。也可能是 bind 在了不同网卡但同一个端口上,仔细看 ss -tulnp 的 Local Address 列。
第五个是 top 的 CPU 加起来不到 100%。这是正常的,因为 %Cpu(s) 那行里 us 、 sy 、 ni 、 id 、 wa 、 hi 、 si 、 st 加起来才是 100%。如果 st (steal time)很高,说明是虚拟机,宿主机把你的 CPU 抢走了,这种情况自己优化没用,得找平台方。
7.3 把常用命令固化下来的几个小技巧
每次手敲这一串命令太累,几个办法可以省事。
第一个是写 alias。把 ps -eo pid,ppid,user,%cpu,%mem,stat,etime,cmd --sort=-%cpu | head -15 这种长命令缩成 pcpu , free -h 缩成 mem ,放进 ~/.bashrc 里。
alias pcpu='ps -eo pid,user,%cpu,%mem,stat,etime,cmd --sort=-%cpu | head -15' alias pmem='ps -eo pid,user,%cpu,%mem,rss,cmd --sort=-rss | head -15' alias ports='ss -tulnp' alias disks='df -h; echo; df -i'
第二个是写一个诊断脚本,把最常用的一组命令打包输出,起名叫 syscheck.sh ,需要的时候一跑,所有信息一次性出来。
#!/bin/bash echo "===== 系统概览 =====" hostnamectl | head -6 uptime echo "===== CPU =====" lscpu | grep -E 'Model name|^CPU\(s\)|Socket|Thread' echo "===== 内存 =====" free -h echo "===== 磁盘容量 =====" df -h -x tmpfs -x devtmpfs echo "===== inode =====" df -i -x tmpfs -x devtmpfs echo "===== 磁盘 IO =====" iostat -x 1 2 | tail -20 echo "===== 高 CPU 进程 =====" ps -eo pid,user,%cpu,%mem,stat,etime,cmd --sort=-%cpu | head -10 echo "===== 高内存进程 =====" ps -eo pid,user,%cpu,%mem,rss,cmd --sort=-rss | head -10 echo "===== 监听端口 =====" ss -tulnp
第三个技巧是用 watch 做定期刷新,适合盯某个指标的变化:
watch -n 2 'free -h; echo; df -h /data'
-n 2 是每两秒刷新一次。 watch -d 还能高亮变化的部分,看绝对值变化特别直观。
第四个是输出重定向归档。排查问题时把结果存下来,事后复盘或者给同事看都方便:
syscheck.sh > /tmp/syscheck_$(date +%F_%H%M).log 2>&1
用时间戳命名,多次执行不会互相覆盖。这些日志攒一段时间,对比不同时间点的数据,很多缓慢劣化的问题就浮出来了。
聊到这儿基本把 Linux 系统信息查看的主干命令过了一遍。我自己这些年最大的体会是,命令本身两三天就能背熟,真正花时间的是建立"看到数值知道意味着什么"的直觉,而这个只能靠在真实故障里一次次对照、记录、复盘慢慢养。上面那张速查表和那个诊断脚本,是我自己在实际运维中反复改过好几版留下来的,你拿去按自己的环境稍微调整一下字段就能用,比临时抱佛脚翻文档靠谱得多。
以上就是Linux服务器性能排查常用命令大全:CPU内存磁盘网络一次看懂的详细内容,更多关于Linux性能排查命令的资料请关注脚本之家其它相关文章!


最新评论