
接手 Linux 服务器第一件事往往是确认这台机器当前还扛不扛得住。接口响应变慢、服务告警、磁盘写满大多数故障现场都能通过几个基础命令快速定位lscpu看 CPU 硬件配置w看系统负载top看动态资源占用free看内存df看磁盘。这五个命令单看任何一个都不复杂但它们组合起来就是一套“负载、CPU、内存、磁盘”的快速体检流程。很多刚接触 Linux 的人会把top和free的输出当成静态数字读其实每个字段背后都有明确的语义和使用边界。比如 load average 高不等于 CPU 高free显示的 free 小不等于内存不足df有空间不等于文件系统真的可写。这篇文章会把这五个命令从输出字段、常用参数、判断标准到排查组合拆开讲清楚并给出一个完整的故障排查案例和生产环境可复用的检查清单。1. 先从“服务器变卡”开始理解这组命令的分工服务器卡顿在 Linux 上通常表现为登录慢、命令执行延迟、接口超时、日志写不进去。这时候需要回答的问题不是随口一句“机器负载高”而是更具体地确认 CPU、内存、磁盘这三个最核心资源分别处于什么状态。lscpu、w、top、free、df各自的定位不同组合起来才能覆盖一个最小排查闭环。1.1 一条完整的资源排查链路排查资源问题时推荐从“整体到局部”展开先看系统负载使用w或uptime确认 load average 是否长期超过 CPU 核数。再看 CPU 明细使用top确认用户态、系统态、IO 等待、被虚拟机偷走的时间占比。接着看内存使用free -h重点看 available 和 swap而不是只看 free。然后看磁盘使用df -h和df -i同时确认容量和 inode 是否充足。最后回到进程使用top的交互排序找到占用最高的进程再结合线程分析定位根因。这套顺序保证了在定位某个进程之前你已经知道系统整体处于什么状态。如果一上来就ps aux --sort-%cpu看到某个 Java 进程 CPU 很高可能会忽略 IO 等待持续拉高负载这个更隐蔽的问题。1.2 五个命令的分工对比命令主要解决的问题关键输出适用场景lscpuCPU 硬件信息是否匹配、核数是否足够架构、逻辑 CPU、物理核心、频率、缓存排查性能容量、容器配额、选型核对w系统最近和当前负载、登录用户load average、当前用户活动第一眼判断系统是否已经饱和top动态观察 CPU 和内存占用定位进程%Cpu(s)、进程列表、累计 CPU 时间定位是哪个进程在消耗资源free物理内存和 swap 使用情况total、used、available、buff/cache判断内存是否紧张、是否需要扩容df文件系统容量和 inode 使用情况Size、Used、Use%、Mounted on、IUse%磁盘告警、写不进去、清理空间1.3 学习环境与生产环境的差异在虚拟机或容器里练习这些命令时输出可能和生产环境不同。lscpu在虚拟机里看到的是虚拟化层透传的 CPU 信息free在容器里显示的是宿主机内存top在容器里可能看到宿主机的全部进程也可能只看到容器进程这取决于 pid namespace 和/proc的挂载方式。所以学习阶段重点是理解字段含义生产阶段则要结合容器和云环境的隔离机制做判断。2. lscpu确认 CPU 架构、核心数与频率lscpu是 util-linux 包提供的命令用来汇总 CPU 架构信息。它的数据来源主要是/proc/cpuinfo和/sys/devices/system/cpu/虚拟化环境下还会读取 hypervisor 暴露的信息。日常排查里用得最多的是确认逻辑 CPU 数、物理核心数、架构类型以及是否支持虚拟化。2.1 基本用法和典型输出直接执行lscpu可以看到类似下面的输出Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 46 bits physical, 48 bits virtual CPU(s): 8 On-line CPU(s) list: 0-7 Thread(s) per core: 2 Core(s) per socket: 4 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 85 Model name: Intel(R) Xeon(R) Gold 6148 CPU 2.40GHz Stepping: 4 CPU MHz: 2399.996 BogoMIPS: 4799.99 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 1024K L3 cache: 28160K NUMA node0 CPU(s): 0-7这段输出里最容易被误读的是 CPU(s)、Core(s) per socket 和 Socket(s) 的关系。2.2 关键字段和判断公式逻辑 CPU 总数、物理核心数、线程数之间有一个固定换算关系逻辑 CPU 数 Thread(s) per core * Core(s) per socket * Socket(s) 物理核心数 Core(s) per socket * Socket(s)以上面的输出为例2 * 4 * 1 8所以CPU(s): 8表示这台机器有 8 个逻辑 CPU但物理核心数是 4因为开启了超线程。不同字段的使用场景如下字段含义使用场景ArchitectureCPU 指令集架构如 x86_64、aarch64下载二进制包、编译参数判断CPU(s)逻辑 CPU 总数和 load average 做对比Thread(s) per core每个物理核心的超线程数判断是否有超线程Core(s) per socket每个物理 CPU 的核数计算物理核心总数Socket(s)物理 CPU 插槽数多路服务器判断Model nameCPU 型号和主频判断 CPU 代次CPU MHz / max / min当前频率、最大最小频率判断是否降频NUMA node(s)NUMA 节点数大内存、多路服务器调优lscpu -e可以以表格形式展示每个逻辑 CPU 的详细信息适合写脚本判断 CPU 在线状态。lscpu -p输出可解析格式适合被其他程序处理。2.3 输出不完整或型号不展示时怎么处理有些场景下lscpu不展示型号比如极简容器、精简内核、部分 ARM 环境、util-linux 版本过旧或者/proc/cpuinfo被 seccomp、容器运行时约束。不要急着认为命令坏了按顺序检查先看lscpu -V确认 util-linux 版本。再执行cat /proc/cpuinfo | grep -i model namex86 环境通常能看到型号。ARM 环境可以查看cat /proc/cpuinfo | grep -i Hardware。容器环境可以检查/sys/devices/system/cpu是否存在。有权限时用dmidecode -t processor获取更底层的 CPU 信息。注意容器里lscpu看到的逻辑 CPU 可能是宿主机数量但容器实际能用的 CPU 由 cgroup 限制。判断容器配额要看 cgroup 文件而不是只看lscpu的输出。2.4 排查中容易误读的 CPU 指标换服务器或扩核后第一件事就是跑lscpu确认逻辑核数。比如 4C8G 的云主机通常是 4 个 vCPU也就是 4 个逻辑 CPU对应 load average 超过 4 才属于 CPU 饱和的临界线。如果是开启超线程的物理机8 个逻辑 CPU 的承受能力并不等于 8 个物理核因为超线程共享执行单元密集计算场景下的收益没有逻辑核数那么高。3. w先看系统负载再判断是否要深入排查w命令输出的第一行其实和uptime等价但比uptime多了一个当前登录用户的活动列表。它的核心价值在于一条命令同时回答“系统最近忙不忙”和“现在谁在干什么”两个问题。3.1 w 输出逐列解读15:23:26 up 10 days, 2:34, 2 users, load average: 0.08, 0.03, 0.01 USER TTY FROM LOGIN IDLE JCPU PCPU WHAT root pts/0 192.168.1.10 15:20 2.00s 0.04s 0.04s top字段含义字段含义USER登录用户TTY登录终端FROM来源 IP 或主机名LOGIN登录时间IDLE终端空闲时间JCPU该终端连接的所有进程累计占用的 CPU 时间PCPU当前进程占用的 CPU 时间WHAT当前正在前台执行的命令w -h可以去掉标题行w -s使用短格式w -f可以开关 FROM 列的显示。脚本里如果需要拿到负载数值推荐直接解析cat /proc/loadavg或uptime而不是解析w的表格。3.2 load average 到底是什么load average 的三个数字分别代表过去 1 分钟、5 分钟、15 分钟的平均运行队列长度。运行队列里包含两类进程TASK_RUNNING正在运行或等待 CPU 的进程。TASK_UNINTERRUPTIBLE处于不可中断睡眠状态的进程典型场景是等待磁盘 IO、等待部分内核资源。因此 load average 高不一定意味着 CPU 计算密集也可能是有大量进程堵在 IO 等待上。这就是为什么只看 load average 还不够后续必须用top看wa列来区分原因。3.3 负载高低的判断标准判断负载是否过高关键是和逻辑 CPU 数对比场景判断方式单核机器load average 长期大于 1说明已经过载4 核机器load average 超过 4说明 CPU 或 IO 接近饱和8 核机器load average 超过 8需要立即定位云主机突发流量1 分钟均值高、15 分钟均值低多是短时冲击持续恶化1 分钟、5 分钟、15 分钟都高说明问题持续存在更稳妥的方法是同时观察趋势。如果 1 分钟负载高于 15 分钟负载说明系统正在变忙如果三个值都高说明运维处置前已经持续过载一段时间了。3.4 w 与 uptime 的复用关系w第一行和uptime是完全相同的信息来源。如果只是想知道负载用uptime更轻量uptime15:23:26 up 10 days, 2:34, 2 users, load average: 0.08, 0.03, 0.01要查看当前登录人员和命令活动时再用w。实际运维里w常用于回答“谁在这台机器上操作了什么”而uptime更适合快速确认负载趋势。4. top动态观察资源占用定位消耗进程top是这五个命令里信息量最大的一个。它既能动态刷新 CPU 和内存使用率也能按 CPU、内存、累计 CPU 时间排序进程甚至在交互模式里直接发送信号给进程。理解top的输出是 Linux 性能排查的基本功。4.1 首部信息逐行解读top - 15:24:10 up 10 days, 2:35, 2 users, load average: 0.08, 0.03, 0.01 Tasks: 210 total, 1 running, 209 sleeping, 0 stopped, 0 zombie %Cpu(s): 3.2 us, 1.1 sy, 0.0 ni, 95.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.1 st MiB Mem : 7980.8 total, 3562.4 free, 1420.6 used, 2997.8 buff/cache MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 5573.2 avail Mem第一行的登录用户数和负载与w一致。Tasks 行显示进程总数、运行中、睡眠、停止、僵尸进程数量。僵尸进程数量持续增长时需要检查父进程为什么不回收子进程。%Cpu(s)是 CPU 使用率的核心各列含义如下列名含义排查关注点us用户态 CPU 占用业务进程计算密集时偏高sy系统态 CPU 占用系统调用、内核处理偏高时说明内核路径有压力ni被 nice 调整过的用户态进程占用正常不高id空闲 CPU越低说明越繁忙waIO 等待磁盘慢或存储故障时非常高hi硬件中断网络和硬件设备中断频繁时会高si软件中断网络软中断多时会高st被 hypervisor 偷走的时间云服务器宿主机争抢严重时会高Mem和Swap行与free的含义基本一致。要注意不同版本top的内存单位可能是 KiB也可能是 MiB可以用E键切换显示单位。4.2 进程列表里的关键列PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 1234 root 20 0 1621532 210456 8364 S 8.3 2.6 12:34.56 java关键字段字段含义说明PID进程 ID后续用 kill、strace、jstack 都靠它PR内核调度优先级数字越小优先级越高NInice 值调整进程优先级时使用VIRT虚拟内存总量包含共享库、映射文件不能直接代表物理占用RES常驻物理内存进程实际占用的物理内存SHR共享内存多个进程可共享的部分S进程状态R 运行、S 睡眠、D 不可中断、Z 僵尸、T 停止%CPUCPU 使用率相对单个逻辑 CPU 的百分比%MEM物理内存占比RES / totalTIME累计 CPU 时间进程启动以来累计消耗的 CPU 时间有一个常见误区%CPU超过 100 不代表异常。top里的%CPU是相对单个逻辑 CPU 的百分比多线程进程可以累计多个逻辑 CPU。8 核机器上一个 Java 进程占满 4 个核时top中可能显示 400%。4.3 常用交互快捷键进入top界面后常用键位如下快捷键作用P按 CPU 使用率排序M按内存占用排序T按累计 CPU 时间排序N按 PID 排序R反向排序1展开或折叠每个逻辑 CPU 的使用率H切换线程模式观察进程内部线程k向进程发送信号默认 SIGTERMr修改进程 nice 值c显示完整命令行f选择要显示的字段q退出排查高 CPU 问题时按P排序是最快的定位方式。但如果%Cpu(s)中wa很高按P排序反而可能排不到真正的 IO 等待进程这时应该按S状态找到D状态的进程或者到下一层用iostat、iotop确认磁盘问题。4.4 用批处理模式把 top 接入脚本top也可以非交互运行常用于记录现场快照top -b -n 1 | head -30top -b -n 1 -o %CPU | head -30-b表示批处理模式-n 1表示只输出一轮-o %CPU指定按 CPU 排序。如果系统不支持-o可以先用top -bn1取原始输出再通过sort处理。要监控指定进程可以用top -b -n 1 -p 1234进入线程视角排查 Java 或 Go 应用时结合线程号分析top -H -p 1234注意容器里执行top时如果/proc没有隔离看到的是宿主机全部进程即使 PID namespace 隔离CPU 统计也可能仍是宿主机视角。容器内资源判断要结合 cgroup 文件不能只依赖top。5. free看懂内存占用区分 cache 与真实使用free命令用于查看物理内存和 swap 的使用量。很多新人对内存的认知停留在“free 少就是内存不足”但在 Linux 上空闲内存被用作 page cache 是正常行为真正的判断指标是available。5.1 输出字段解析total used free shared buff/cache available Mem: 7980 1420 3562 30 2997 5573 Swap: 2048 0 2048各列含义列名含义total总内存used已使用的内存free完全空闲的内存sharedtmpfs 等共享内存buff/cache块设备缓冲和页面缓存available估算的可用于启动新应用的内存available是一个估算值它会考虑当前有多少 cache 可以被回收、有多少内存实际空闲、有多少 swap 可用。它比free列更能反映真实可用内存因为当应用申请内存时内核可以回收部分 page cache 分配给进程。5.2 buffers 和 cache 的区别虽然free经常把 buff/cache 放在一列但两者并不相同名称本质典型内容buffers文件系统元数据和块设备缓冲目录项、块设备映射cache页面缓存读取过的文件内容加速后续访问二者都属于内核可以回收的内存。大量读写文件后buff/cache升高是 Linux 使用空闲内存提升 IO 性能的机制不是内存泄漏。5.3 常用参数与轮询监控free -h使用人类可读单位是日常最常用的形式。free -m free -g强制以 MiB 或 GiB 显示适合脚本解析。注意不同版本可能显示 MiB 或 MB脚本解析时优先读取/proc/meminfo。free -s 3每 3 秒刷新一次适合观察内存变化趋势。free -t在末尾增加物理内存和 swap 的总计行。判断内存压力时经验顺序是available是否持续很低。swap的 used 是否增长。系统日志里是否出现 OOM。top中哪个进程占用了大量RES。5.4 为什么在容器里看 free 不准确容器中执行free默认看到的是宿主机内存而不是容器分配的内存。要判断容器是否接近内存上限需要读取 cgroupcgroup v1cat /sys/fs/cgroup/memory/memory.limit_in_bytes cat /sys/fs/cgroup/memory/memory.usage_in_bytescgroup v2cat /sys/fs/cgroup/memory.max cat /sys/fs/cgroup/memory.current如果容器内存达到限制可能触发 OOM kill 或页缓存回收表现是进程突然消失或性能下降但free看起来却“还有很多内存”。6. df查看磁盘容量、文件系统与 inodedf是磁盘排查的第一入口。它从文件系统超级块读取统计信息显示的是整个文件系统的容量而不是某个目录的大小。使用df -h可以快速看到可读性较高的输出。df -hFilesystem Size Used Avail Use% Mounted on /dev/vda1 40G 18G 20G 48% / tmpfs 3.9G 0 3.9G 0% /dev/shm6.1 输出字段解析字段含义Filesystem文件系统设备名或来源Size总容量Used已使用容量Avail可用容量Use%使用率Mounted on挂载点df -h显示空间不足时先确认是根分区还是数据盘告警。使用df -h /var/log可以只看某个路径所在文件系统的容量。6.2 常用参数-T、-i、-x、-adf -hT显示文件系统类型如 ext4、xfs、tmpfs、overlay、fuse。遇到新挂载盘或容器镜像层时这个参数能帮助理解为什么会有大量特殊文件系统。df -i显示 inode 使用情况。inode 是文件系统保存文件元数据的结构每个文件或目录至少要占用一个 inode。inode 用尽后即使磁盘有剩余空间也无法创建新文件。df -x tmpfs -x devtmpfs排除 tmpfs、devtmpfs 等虚拟文件系统避免输出被内存盘干扰。df --total在末尾显示总计。6.3 磁盘空间与 inode 属于两个维度磁盘空间和 inode 是两个独立维度。经常出现的故障是df -h显示仍有余量但touch test.txt报No space left on device。使用df -i后发现IUse%已经接近 100%。典型的 inode 耗尽场景是小文件数量极大的目录比如邮件队列、临时文件目录、未清理的日志目录。处理方式用df -i确认哪个文件系统 inode 满了。用du -x --inodes / 2/dev/null | sort -nr | head找出 inode 数量大的目录。注意du --inodes需要较新版 coreutils。清理无用的小文件或迁移到其他文件系统。6.4 文件被删除但 df 空间不释放另一个经典坑du -sh /统计出来的总量远小于df -h的 Used。常见原因是有文件被删除但仍有进程持有这个文件的操作句柄文件占用的空间不会真正释放。排查方式lsof L1或lsof | grep deletedL1表示列出 link count 为 0 但仍被打开的文件。找到进程后重启进程或让进程释放句柄磁盘空间才会真正回收。这也是线上清理日志后空间没有立刻下降的原因之一。7. 组合实战一次 CPU 负载高的完整排查单独记命令很快真正困难的是遇到真实故障时把命令按正确顺序组合起来。下面用一个常见场景演示完整排查链路。7.1 现象与初始判断线上 Java 服务突然响应变慢用户反馈接口超时。运维人员 SSH 登录后终端操作有明显延迟。此时不能直接 kill 进程先按“负载 - CPU - 内存 - 磁盘 - 进程”的顺序做现场快照。第一步执行uptime14:20:31 up 20 days, 3:12, 3 users, load average: 18.32, 15.10, 10.02这台机器是 8 逻辑 CPUload average 高达 18说明系统已经明显过载。接下来用top看 CPU 状态。top -b -n 1 | head -20%Cpu(s): 85.0 us, 10.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 5.0 si, 0.0 stus高、wa低、id接近 0说明是 CPU 密集不是 IO 等待。再看进程列表按 CPU 排序top -b -n 1 -o %CPU | head -20发现某个 Java 进程%CPU达到 700%说明该进程已经占满了约 7 个逻辑 CPU。7.2 继续验证内存和磁盘CPU 高的同时还要排除内存和磁盘干扰free -htotal used free shared buff/cache available Mem: 7.8G 5.2G 1.1G 112M 1.5G 2.0G Swap: 2.0G 0B 2.0Gavailable 还有 2.0Gswap 没有增长内存暂时没有成为瓶颈。df -h df -i磁盘容量和 inode 使用都在正常范围。因此可以收敛结论问题集中在 Java 进程的 CPU 消耗。7.3 定位到线程和执行动作CPU 高不直接等于代码有问题可能是正常流量、垃圾回收、死循环或线程竞争。先看进程内线程top -H -p $(pgrep -f YourJavaApp | head -1)也可以使用ps -L -p $(pgrep -f YourJavaApp | head -1) -o pid,tid,pcpu,stat,comm --sort-pcpu | head记录 CPU 占用最高的几个线程号再把线程号转成 16 进制通过jstack找到对应线程栈判断是 GC 还是业务逻辑问题。这一步之后才可以根据结果决定是否调整 JVM 参数、优化代码、扩容机器或限流。这里的关键不是死记命令而是保持排查顺序先确认 load再确认 CPU 分布再排除内存和磁盘最后深入线程栈。一次完整的现场快照应该同时记录时间、负载、CPU 百分比、进程占用、内存、磁盘便于后续复盘。8. 生产环境实践建议与排查清单命令行学习容易生产环境用出价值难。最后整理几条实践建议和一份可复制到故障时的排查清单。8.1 排查时先做数据快照故障现场转瞬即逝登录后先保存一轮快照再分析。一条简单的命令就能完成{ date