Linux服务器监控命令实战:从top到iostat的排查指南

发布时间:2026/10/6 3:33:36
Linux服务器监控命令实战:从top到iostat的排查指南 做运维这行跟服务器打交道是每天的必修课。我见过不少同事机器一亮红灯就到处翻常用命令大全临时抱佛脚。其实服务器运维监测没那么玄乎翻来覆去就是那么几十条命令关键是你得知道每条命令在什么场景下用、输出怎么看、哪些指标才是真正要命的。这篇内容我不打算给你列一个几百条的清单那没有意义。我想从一个实际干活的角度把日常巡检、故障排查时真正高频用到的监测命令拆开揉碎讲清楚原理、参数和实战场景顺便把我这些年踩过的坑一并交代了。这套内容适合刚入行的运维工程师、兼职管服务器的后端开发以及那些被老板要求顺便看下服务器的全栈同学。反正不管你是用云服务器还是自建机房主流Linux发行版上这些命令基本通用看完可以直接对着终端实操。1. 先搞清楚监测什么从目标反推命令很多人学命令是零散的今天看到一个top觉得有用明天看到一个iostat又收藏起来真到用的时候脑子里一团浆糊。我建议换个思路——先确定你要监测什么目标再去找对应命令。只有这样才能建立自己的排查体系。1.1 监测体系的四个核心维度服务器监测说白了就四件事资源用没用完、网络通不通、进程活没活着、业务还慢不慢。对应到系统层面就是CPU、内存、磁盘IO和网络对应到命令层面就是top/vmstat、free/sar、iostat/df、ping/ss/tcpdump这几组工具。举个例子用户反馈网站打开很慢你先别急着重启服务。第一步看uptime判断系统负载高不高第二步看top定位是CPU被打满还是内存不够触发swap第三步用iostat看看磁盘是不是在疯狂读写最后用ss确认连接数是否异常。这个排查链路就是由目标驱动命令选择的过程。如果没有体系你大概率会东敲一下西敲一下最后只能重启大法。1.2 理解两条时间线实时快照与持续趋势监测命令还得分两类一类是实时快照型抓的是当前瞬间的状态比如top、ps、free另一类是持续趋势型能按时间窗口记录历史数据比如sar、vmstat带间隔参数跑一段时间、iotop持续刷新。日常巡检两种都要用。快照型适合登录服务器那一刻快速判断有没有问题趋势型适合在问题发生时拉长观察窗口确认是偶发还是持续。我见过有同事拿top按一次空格就说CPU不高啊结果问题在凌晨三点出现这就是只看快照不看趋势的典型失误。生产环境建议把趋势型命令配合定时任务写进监控脚本这样你睡觉的时候脚本还在替你盯着机器。2. 系统负载与CPU监测看懂top、vmstat和uptime资源监测里面CPU最容易理解但恰恰也是最容易误判的。很多新手看到top里的CPU百分比超过80%就慌了实际上CPU高不等于有问题关键要看是用户态的高还是等待IO的高这完全是两回事。2.1 uptime与load average别被负载数值骗了uptime会输出三组负载均值分别代表过去1分钟、5分钟、15分钟的平均活跃进程数。注意这个值对多核CPU有特殊意义——负载5在单核机器上已经算饱和但在四核机器上只用了大约四分之三的算力。所以我通常用负载除以核数来判断繁忙程度比值超过0.7就要留意超过1.0基本算满载。我踩过的坑是某次线上机器负载冲到30多我第一反应是CPU不够结果一看核数才知道是64核的物理机31的负载连一半都没用上。所以看负载前先执行nproc确认核数这个习惯能避免不少误判。另外三个时间点的数值差异也有讲究——1分钟远高于15分钟说明是突发负载可能是定时任务在跑或流量尖峰三个值都高且稳定说明服务器已经持续高负荷运转需要扩容或优化业务逻辑。2.2 top与htop交互式资源监视的关键字段top是进服务器后几乎必敲的第一条命令。但很多人只会看CPU和MEM两列其实最关键的是上面那几行统计信息。%Cpu(s)里的us表示用户态占用sy是内核态占用wa是等待IO完成的时间——如果wa很高而us不高说明CPU在等磁盘或网络瓶颈根本不在CPU上。st代表被虚拟机管理程序偷走的时间云服务器上st偏高说明隔壁邻居在抢资源。进程列表里我一般按大写P键按CPU排序看谁在吃计算资源按M键按内存排序看谁是内存大户。还要养成按H键切换线程视图的习惯有些问题是某个进程里特定线程卡死导致的只看进程级根本定位不到。htop是top的增强版支持鼠标操作和树形进程展示新机器我通常直接装htop它对人类友好太多但脚本里解析还是得靠top -bn1这种批处理模式。2.3 用vmstat定位CPU等待与内存瓶颈vmstat 1 5的意思是每秒采样一次连续采5次。输出里的r列代表运行队列中的进程数这个值长期大于核数说明CPU算力不够b列是阻塞在IO上的进程数经常大于0就要怀疑磁盘出问题了。us和sy分别对应user和system占用率sy老高的话可能是频繁的系统调用比如文件读写太多或网络中断过密。vmstat最值钱的是si和so两列——swap in和swap out。只要这两个数字持续不为0说明物理内存已经不够用系统正在用磁盘充当内存。这个状态非常伤性能因为磁盘读写速度和内存差着几个数量级。我曾经处理过一台内存4G的机器跑Java应用so每秒几十兆整个服务卡到几乎不可用最后解决办法不是调JVM参数而是直接加内存条。所以看到swap活动先别调优先想物理内存是不是真的不够了。3. 内存与磁盘监测free、df、iostat配合使用内存和磁盘是连在一起的冤家——内存不够会swap到磁盘磁盘IO慢会拖慢所有进程。所以排查的时候这两块要一起看。3.1 free命令看懂buffer/cache和availablefree -h输出里最容易误解的是buff/cache这一列。不少新手看到缓存占了好几个G就紧张以为内存泄漏其实这是Linux的正常行为——它把空闲内存用来缓存文件读取一旦应用需要内核会立刻回收这部分内存。真正该看的是available这一列它表示可供新应用使用的内存估计值比used更有参考意义。判断内存够不够用我的经验是看available占总内存的比例长期低于20%就该告警了。另外free建议加-w参数看详细列能区分buffer和cache——buffer是块设备缓冲cache是文件页缓存虽然日常排查不用分得那么细但真遇到诡异问题区分这俩有助于缩小排查范围。3.2 实时查看内存排名与OOM风险监控内存除了free看总量还得知道谁在吃内存。ps aux --sort-%mem能按内存占用降序排列进程一眼找出内存大户。每次我在服务器上看这个命令的输出排第一的一般是Java进程或Elasticsearch这是常态不是异常。真正要警惕的是OOM Killer。当系统内存耗尽内核会挑一个进程杀掉来释放内存这往往导致服务突然挂掉。查看dmesg -T | grep -i oom或journalctl -k -f能看到OOM记录。我遇到过数据库在凌晨被OOM干掉的情况原因就是前一天业务导入数据时内存暴涨而导入完成后内存没及时回收。所以内存监测的日常姿势是跑一个定时任务记录free -h的输出同时监控dmesg有没有OOM痕迹双管齐下才稳。3.3 磁盘容量与inodedf命令的两个维度df -h看容量df -i看inode两条都要会。硬盘满了是个小问题好排查inode满了才是隐蔽杀手——文件系统能创建的条目数是有限的哪怕磁盘还剩几十Ginode耗尽了一样写不进任何新文件。我之前在给客户排查服务器报磁盘满但df显示还有空间的问题时就是靠df -i发现inode使用率100%一查全是邮件系统的死信文件和小缓存文件几十万个小文件把inode占满了。清理起来也费劲要find /var -type f -size 1k逐个找源头这种经验你光看文档是学不来的。顺带说一句du -sh和du -sh .[!.]*配合能找到隐藏文件的大小清理磁盘时不能漏。3.4 iostat与iotop磁盘IO性能分析iostat -x 1 3能按设备输出详细IO统计。%util是最多人看的指标但我要提醒一句%util在传统的机械盘上基本等于磁盘利用率但在SSD和云盘上意义已经弱化因为硬件支持并发IO%util到100%也可能只是瞬时高并发。更可靠的指标是await——平均每次IO请求的处理时间机械盘通常几十毫秒正常SSD应该在个位数毫秒级别一旦await飙高说明磁盘响应变慢。iotop则是看哪个进程在捣乱。执行iotop -o只看有IO操作的进程你能直观看到某进程磁盘读速率几十MB/s在拖垮磁盘。上次排查数据库慢查询我就是靠iotop发现有个备份进程在高峰期全量打包日志和业务抢IO后来把备份任务错峰执行就解决了。注意iotop需要root权限没有的话用pidstat -d一样能看到每进程的读写速率。4. 网络监测连通性、端口与连接状态排查网络问题是运维里最让人头大的类型。因为链路涉及的环节太多——本机网卡、交换机、路由器、防火墙、对方服务器任何一环出问题都会表现为连不上排查命令自然也要分层。4.1 ping与mtr连通性测试的正确姿势ping是最基础的连通性测试但很多人只会ping几下网关就完事。我建议用ping -c 10看丢包率如果丢包大于1%就要警惕链路质量。另外mtr命令强烈推荐它是traceroute的增强版能持续显示从本机到目标的每一跳丢包率和延迟快速定位是局域网内丢包还是公网出口问题。遇到云服务器可以Ping通但业务连不上的情况基本可以排除链路问题重点转向端口监听和防火墙。Ping通只证明网络层的ICMP协议通不代表TCP端口能连这是两类完全不同的问题。我处理过无数次这种工单用户信誓旦旦说网络没问题结果最后发现是安全组或iptables没放行端口。4.2 ss命令端口监听与连接状态速查ss -tlnp查TCP监听端口-u换成UDP-p显示进程信息。很多老教程还在推荐netstat但netstat在处理大量连接时又慢又耗CPUss内核直接读套接字信息效率高一个量级。连接状态里我最关注ESTABLISHED的数量是否异常上升——如果某服务established连接数持续暴涨要么是流量真的来了要么就是连接泄漏没释放。ss -s能给出全系统连接统计摘要TIME_WAIT状态的连接大量堆积时通常需要检查代码里连接池是否正确复用。过高TIME_WAIT有个解决思路是开启tcp_tw_reuse和调整tcp_fin_timeout但不建议无脑开有的环境开了反而引发问题。端口数不够时用ss -lnt看listen队列溢出情况如果Send-Q数值大于0说明有连接被丢弃这时候要调net.core.somaxconn和应用程序自己的队列参数。4.3 实时带宽与流量监控外部的ifstat和iftop可以实时看网卡流量iftop -n -P能看到每个连接的传输速率和端口对定位哪台机器在偷跑带宽特别有用。有一次用户说服务器流量异常出口带宽打满我上机器跑iftop一眼看到一个非业务端口正和某个IP大量通信——带宽跑满直接顺藤摸瓜找到问题。从网卡角度看sar -n DEV 1 3能统计每块网卡的收发包量和错误包rxdrop和txdrop有数值通常意味着缓冲区不足。云服务器遇到持续流量激增时优先想到的是云厂商的安全控制台和流量监控面板它们能提供VPC粒度的流量统计比自己抓包全面得多。完整的抓包分析留给tcpdump下一节单独展开。4.4 tcpdump抓包让网络问题不再玄学tcpdump -i eth0 port 80 -c 100是抓固定端口流量的基础用法。-w保存成pcap文件用Wireshark打开分析-v输出详细协议信息。新手容易忽略权限——抓包一般需要root或者有CAP_NET_RAW能力普通用户执行会报权限错误。tcpdump最常用来验证双方都说自己在发数据但对方没收到。抓包能看到SYN包发出去了没、对端有没有回SYN-ACK、连接在哪一步断了。这个命令是排查网络问题的终极大招比猜和试高效得多。但注意别在业务高峰期长时间抓包抓包本身有一定性能开销生产环境用-c限制包数量抓几十个包够分析就够了。5. 进程与服务监测从看到状态到看懂状态进程监测不只是ps aux看一眼这么简单。每个字段、每种状态都有明确含义组合起来能告诉你系统到底在经历什么。5.1 ps命令状态字段深度解读ps aux的输出里STAT字段非常关键。S表示可中断睡眠正常等待资源R是运行中D是不可中断睡眠——通常是等IO大量D状态进程出现说明IO子系统出问题。Z是僵尸进程出现一两只是程序正常的fork-收尸时序扎堆出现就要检查父进程为什么不回收子进程。排查内存泄漏或线程问题时ps -T -p PID能列出指定进程的所有线程pstree -p PID能以树状展示父子关系。我在定位一次PHP-FPM子进程异常增多的问题时靠ps -eLf统计线程数发现单个请求竟然fork出上百个子进程最后定位到业务代码里无限递归创建进程的bug这种问题不敢想象没有进程树分析工具怎么查。5.2 systemctl与journalctl现代服务守护排查体系CentOS 7和Ubuntu 16以后统一走systemd体系systemctl status 服务名一条命令能看运行状态、主进程PID、最近日志、监听端口等关键信息。systemctl list-units --failed能列出所有启动失败的单元服务器重启后先跑它准没错。journalctl -u 服务名 -f能实时跟踪某服务的日志输出journalctl -u 服务名 --since 1 hour ago查最近一小时日志。这套体系比老SysVinit的service命令信息量大多了。我还习惯用journalctl -p err -b查看本次开机以来所有错误级别日志快速了解启动过程有没有异常。5.3 用lsof和strace精确到卡住的调用服务卡死是最难排查的问题之一。lsof -p PID列出某进程打开的所有文件包括普通文件、socket、管道等——连接数异常时能看到进程到底还持有多少文件描述符。默认limit一般是1024高并发应用很容易撞上此时ulimit -n和/etc/security/limits.conf一会儿说。往下钻取strace -p PID能实时打印进程的系统调用序列。当服务无响应时strace会显示它停在哪个系统调用上——通常是read等你或者卡在某个锁上。这个方法定位代码到底卡在哪非常锋利我解决过一次Java进程CPU 100%但堆没溢出的疑难问题jstack看一眼线程dump发现有个线程在无限循环做正则匹配strace确认了这个线程的调用链路问题瞬间清晰。注意strace对性能有影响生产环境不要长时间挂抓几秒就够。6. 把命令串成巡检脚本从人盯到脚本盯运维终极目标不是你会敲多少命令而是能不能把常用操作固化下来让机器自己替你做采集和告警。这个环节我分享一个我一直在用的巡检脚本思路。6.1 巡检脚本的四大模块设计我维护的巡检脚本分四个模块系统资源内存、CPU、负载、swap、磁盘状态使用率、inode、磁盘IO、网络状态丢包率、TCP状态统计、监听端口、关键服务进程存活性、端口响应。脚本核心逻辑是用命令采集数据然后做阈值比较和告警输出。实际执行中定时任务cron每5分钟跑一次结果追加进日志文件。写脚本有几个细节经验一是命令路径要写全cron环境变量PATH往往不包含/usr/sbin等目录直接写/usr/bin/free比free稳二是采集结果加时间戳方便事后回溯三是判断条件写成函数新指标直接加函数就行不用改主流程。6.2 一个简洁实用的监测告警样例下面的脚本是基础模板逻辑清晰容易扩展。我在生产环境跑过很长时间直接拷贝就能用。#!/bin/bash # 极简服务器监测告警脚本 THRESHOLD_MEM80 THRESHOLD_DISK90 THRESHOLD_LOAD4 # 采集时间戳 TS$(date %Y-%m-%d %H:%M:%S) # 检查内存使用率 MEM_USE$(free | awk /Mem:/{printf %.0f, $3/$2*100}) if [ $MEM_USE -gt $THRESHOLD_MEM ]; then echo $TS WARN MEMORY $MEM_USE% /var/log/monitor.log fi # 检查磁盘使用率 DISK_USE$(df / | awk NR2{print $5} | sed s/%//) if [ $DISK_USE -gt $THRESHOLD_DISK ]; then echo $TS WARN DISK $DISK_USE% /var/log/monitor.log fi # 检查负载均值一核阈值取1.0多核按核数算 LOAD_NOW$(uptime | awk -Fload average: {print $2} | cut -d, -f1 | tr -d ) if [ $(echo $LOAD_NOW $THRESHOLD_LOAD | bc) -eq 1 ]; then echo $TS WARN LOAD $LOAD_NOW /var/log/monitor.log fi # 检查nginx进程是否存活 if ! pgrep nginx /dev/null 21; then echo $TS ERROR nginx not running /var/log/monitor.log # 这里可以接上重启动作或企业微信通知 fi脚本用数值比较加awk浮点运算不用依赖太多外部工具任何自带bash的主机都能跑。要接告警通知的话在判断里面加curl调用即可——企业微信机器人、钉钉机器人、飞书机器人API都是一通curl的事。6.3 指标留存与趋势分析从监测到预测光有告警还不够日志文件里攒下的指标就是你的金矿。我习惯每天凌晨用sar命令汇总一天的历史数据因为sysstat服务默认会采集系统活动记录。sar -u看CPU趋势sar -r看内存sar -d看磁盘配合sa二进制数据文件仓库能查询任意时间段的数据。有了趋势数据判断磁盘会不会下周满、内存够不够撑到下次扩容就不是拍脑袋了。我在一家公司接班时上一任运维从没看过趋势某天凌晨磁盘满导致数据库写不进去业务停了半小时。我接手后做了个计划任务每周生成磁盘增长率报表问题直接扼杀在摇篮里。这也就是为什么我强调趋势比快照值钱——快照只能告诉你现在坏了趋势能告诉你什么时候要坏。7. 实战复盘一次深夜故障的完整排查过程讲了这么多命令最后用一个真实的排查案例把它们串起来。一次凌晨两点线上一台MySQL服务器出现大量连接超时我登录服务器的排查链路是这样的第一步查负载和资源——uptime显示负载从平时的1.5涨到了12top看到CPU的wa占比超过60%排第一的是一个kworker内核线程在刷盘。这个信号基本指向磁盘IO瓶颈。第二步用iostat -x 1确认磁盘await冲到200多毫秒%util飙到99%确认是磁盘问题。第三步排查是谁在写盘。iotop -o看到两个进程在疯狂写一个mysqld在跑批量更新一个logrotate在做日志切割。晚高峰跑大批量更新本来就够呛日志切割同时叠加更是雪上加霜。第四步看vmstat的b列持续大于10大量进程阻塞在IO等待上服务卡顿的逻辑链彻底闭合。解决办法并不复杂——把logrotate任务从凌晨2点改到凌晨4点错开业务高峰期同时跟业务方确认批量更新改为限速分批执行。第二天观察iostatawait回到个位数所有指标恢复正常。整个过程从发现问题到解决不到40分钟靠的不是什么高端监控平台就是这几条基础命令加一个清晰的排查思路。8. 最后的经验沉淀几个我必须提醒你的细节命令人人会敲差距在细节。我把这几年的实践心得浓缩成下面几条每一条都有血泪代价在里面。第一看任何指标都要结合核数、版本和业务特点。负载要看核数%util要看设备类型内存要看available而不是used这些都是我用真实事故换来的不能盲信单个数字。第二命令输出要留痕。我见过太多人排查时只看命令输出看完就关了后面复盘时啥都拿不出来。建议排查复杂问题时用tee把输出同时写到文件里top -bn1 | tee -a /tmp/capture.log这种写法养成分屏留痕的习惯备查和交接都有底。第三工具只是辅助思路才是核心。你把top、free、iostat、ss这四条命令学透胜过生吞一百条孤立命令。排查问题的本质是定位瓶颈链路工具再多不会分析链路照样抓瞎。第四别忽视日志的力量。命令监测的是现状日志记录的是因果。journalctl、/var/log/messages、应用自己的日志文件配合命令一起看你能得到的答案远比单看命令多得多。比如OOM Killer的记录就在dmesg里你不看日志怎么知道是内核杀了进程呢最后再分享一个小技巧把你自己最常用的十来个命令组合写成一个alias或脚本比如alias topmtop -b -n 1 -o %MEM | head -20省得每次重复敲。我自己的~/.bashrc里这样的别名至少有20个都是长年积累出来的肌肉记忆。运维这活不复杂贵在熟练和有条理希望这篇文章能让你少走点弯路。