核心指标采集:CPU、内存、磁盘、网络
系统监控这件事,说白了就是回答三个问题:资源够不够?哪里是瓶颈?会不会出事? 而回答这些问题,靠的就是对 CPU、内存、磁盘、网络这四大核心指标的精准采集。
我个人习惯把指标采集分为两层:用户态工具层(top、iostat 这些)和 内核数据源层(/proc 文件系统)。工具只是表象,真正有价值的是理解数据从哪里来、怎么解读。今天我们就一层层剥开来看。
CPU 指标:别只看 idle
CPU 监控,新手最容易犯的错就是只看 %idle。我见过太多人盯着 99% idle 说系统很闲,结果业务延迟高得离谱。为什么?因为 CPU 在等锁、等 IO、或者被 steal 了,这些 idle 是「假空闲」。
真正的 CPU 指标,来自 /proc/stat。这个文件每一行代表一个 CPU 核心,第一行是总合计。里面的数字依次是:user、nice、system、idle、iowait、irq、softirq、steal、guest。
# 查看 CPU 总时间片
cat /proc/stat | grep "^cpu "
cpu 1234567 89012 345678 9012345 67890 1234 5678 9012 0
# 解读(单位:USER_HZ,通常 1/100 秒)
# user = 1234567 (用户态)
# nice = 89012 (低优先级用户态)
# system = 345678 (内核态)
# idle = 9012345 (空闲)
# iowait = 67890 (等待 IO)
# irq = 1234 (硬中断)
# softirq = 5678 (软中断)
# steal = 9012 (被虚拟机偷走的时间)
采集原理其实很简单:两次采样做差值,再除以总时间差。比如 5 秒前读一次,5 秒后再读一次,算出每种状态的增量,然后算百分比。
util(100 - idle)、iowait、steal。util 高说明真忙,iowait 高说明磁盘拖后腿,steal 高说明宿主机超卖了。这三个一组合,问题基本能定位。
top 命令其实也是读 /proc/stat。你运行 top 时看到的 %Cpu(s) 行,就是它每隔几秒采样算出来的。我个人更喜欢用 mpstat -P ALL 1,它能实时看每个核心的分布,排查单核瓶颈特别好用。
内存指标:free 命令的陷阱
内存监控有个经典误区——看 free -m 里的 free 列。你以为 free 是 100MB 就快爆了?其实 Linux 把大部分内存拿去做了缓存(cache/buffer),真正可用的内存是 free + buff/cache。
数据源是 /proc/meminfo。这个文件内容很丰富,但核心就几行:
cat /proc/meminfo
MemTotal: 16384000 kB
MemFree: 1024000 kB
MemAvailable: 8192000 kB ← 这才是真正可用的
Buffers: 512000 kB
Cached: 6144000 kB
SwapTotal: 2097152 kB
SwapFree: 1048576 kB
注意 MemAvailable 这一项。它是内核自己估算的「在不触发 swap 的情况下还能分配多少内存」。这个值比 free 靠谱得多。我在项目中遇到过好几次,free 显示只有 200MB,但 MemAvailable 还有 4GB,业务跑得好好的。如果只看 free 就报警,那得被骚扰死。
free -m 的 used 列去算内存使用率。used = total - free - buff/cache,但这样算出来的 used 包含了 cache。实际上 cache 是可以回收的,不应该算作「已用」。正确的做法是用 total - MemAvailable 来算真实使用量。
内存泄漏的监控,我建议关注 /proc/meminfo 中的 Committed_AS。它表示所有进程承诺要用的内存总量。如果这个值超过了物理内存,说明系统已经开始过度承诺,随时可能 OOM。
磁盘指标:iostat 的读法
磁盘监控,核心是看 IOPS(每秒 IO 次数)和 吞吐量(每秒读写字节数),以及最重要的——等待时间。
数据源是 /proc/diskstats。这个文件每行代表一个磁盘或分区,字段很多:
cat /proc/diskstats | grep "sda "
8 0 sda 123456 78901 9876543 123456 654321 98765 12345678 234567 0 345678 456789
字段解读(按顺序):
| 字段 | 含义 | 单位 |
|---|---|---|
| rd_ios | 读完成次数 | 次 |
| rd_merges | 合并读次数 | 次 |
| rd_sectors | 读扇区数 | 512 字节 |
| rd_ticks | 读花费时间 | 毫秒 |
| wr_ios | 写完成次数 | 次 |
| wr_merges | 合并写次数 | 次 |
| wr_sectors | 写扇区数 | 512 字节 |
| wr_ticks | 写花费时间 | 毫秒 |
| in_flight | 正在处理的 IO 数 | 个 |
| io_ticks | IO 总忙碌时间 | 毫秒 |
| time_in_queue | IO 队列总等待时间 | 毫秒 |
iostat 工具就是基于这些字段算出来的。比如 %util = (io_ticks / 采样间隔) * 100%。但注意,%util 到 100% 不代表磁盘就满了,它只表示采样周期内磁盘一直在忙。对于 SSD 来说,%util 到 100% 可能 IOPS 还没到上限。
await(平均 IO 等待时间)。机械盘 await 超过 20ms 就该警惕了,SSD 超过 5ms 就要查原因。另外 svctm(服务时间)如果远小于 await,说明 IO 在排队,队列深度太高了。
网络指标:别漏了丢包和重传
网络监控,带宽利用率当然要看,但真正要命的往往是 丢包 和 重传。带宽跑满只是慢,丢包重传会导致 TCP 连接雪崩。
数据源是 /proc/net/dev。这个文件列出了每个网卡的收发统计:
cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
eth0: 1234567890 987654 0 0 0 0 0 0 9876543210 654321 0 0 0 0 0 0
关键字段:errs(错误包)、drop(丢弃包)。如果 drop 持续增长,说明网卡接收队列满了,可能是中断处理不过来,或者 ring buffer 太小。
还有一个容易被忽略的指标——TCP 重传率。这个不在 /proc/net/dev 里,而在 /proc/net/snmp 或 /proc/net/netstat 中:
cat /proc/net/snmp | grep Tcp
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs RetransTime
Tcp: 1 200 120000 -1 12345 67890 12 34 567 1234567 2345678 1234 5678
重传率 = RetransSegs / OutSegs。正常网络重传率应该低于 0.1%。如果超过 1%,说明网络质量有问题,可能是带宽不够、链路不稳定、或者对端处理不过来。
tx-checksumming 的硬件 offload,导致 /proc/net/dev 统计的 bytes 不准。后来用 ethtool -S eth0 看硬件计数器才找到真相。所以,软件统计不一定可靠,关键场景要交叉验证。
采集工具的选择与对比
工具这么多,怎么选?我个人的建议是分场景:
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 快速排查 | top / htop | 交互式,一眼看全局 |
| CPU 细粒度 | mpstat -P ALL 1 | 每个核心独立展示 |
| 内存详细 | free -h / cat /proc/meminfo | 直接看 MemAvailable |
| 磁盘性能 | iostat -x 1 | 扩展统计,await/svctm 都有 |
| 网络流量 | sar -n DEV 1 | 历史记录,趋势分析 |
| 网络质量 | ss -s / netstat -s | 看 TCP 重传和丢包 |
| 自动化采集 | 直接读 /proc | 轻量、无依赖、适合脚本 |
嗯,这里要注意一点:不要在生产环境频繁跑 top 或 iostat 的交互模式。这些工具本身会消耗 CPU 和 IO。自动化采集时,我都是直接读 /proc 文件,用脚本解析,每 10-60 秒采样一次,对系统影响几乎为零。
最后说一句:工具只是手段,理解原理才是根本。你知道了 /proc/stat 的每一列代表什么,知道了 iowait 和 steal 的区别,知道了 MemAvailable 比 free 更靠谱——那你用任何监控系统都能快速定位问题。这才是我们做监控的意义所在。
公众号:蓝海资料掘金营,微信deep3321