核心指标采集:CPU、内存、磁盘、网络

系统监控这件事,说白了就是回答三个问题:资源够不够?哪里是瓶颈?会不会出事? 而回答这些问题,靠的就是对 CPU、内存、磁盘、网络这四大核心指标的精准采集。

我个人习惯把指标采集分为两层:用户态工具层(top、iostat 这些)和 内核数据源层(/proc 文件系统)。工具只是表象,真正有价值的是理解数据从哪里来、怎么解读。今天我们就一层层剥开来看。

核心观点: 工具会变,但 /proc 下的数据模型十几年没大变。吃透底层,你就能在任何监控系统里游刃有余。
核心指标采集知识体系 四大核心指标采集 CPU 内存 磁盘 网络 数据来源 /proc 文件系统(内核数据源) 用户态工具(top / iostat / free) 关键 /proc 文件 /proc/stat (CPU) /proc/meminfo (内存) /proc/diskstats (磁盘) /proc/net/dev (网络) 采集原理 周期性读取 → 计算差值 → 归一化 → 输出指标

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 秒后再读一次,算出每种状态的增量,然后算百分比。

我的习惯: 监控 CPU 时,我至少看三个指标:util(100 - idle)、iowaitsteal。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_ticksIO 总忙碌时间毫秒
time_in_queueIO 队列总等待时间毫秒

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%,说明网络质量有问题,可能是带宽不够、链路不稳定、或者对端处理不过来。

避坑指南: 我曾经遇到过一个问题——监控显示带宽利用率只有 30%,但业务反馈网络很慢。查了半天才发现是网卡驱动开启了 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