🐧 第07章 · 性能监控
top vmstat iostat sar mpstat
性能监控¶
服务明明"没死"却越来越慢,到底卡在哪?性能问题绕不开四个资源:CPU、内存、磁盘 I/O、网络。这一章教你用 top、vmstat、mpstat、iostat、sar 定位瓶颈,并结合本机的 Prometheus 监控方案讲一讲"长期观测"。
性能四要素¶
| 资源 | 主要命令 | 关注指标 |
|---|---|---|
| CPU | top、mpstat |
us/sy/id/wa、每核占用 |
| 内存 | free、vmstat |
available、si/so(swap) |
| 磁盘 I/O | iostat、iotop |
%util、await、r/s、w/s |
| 网络 | ss、sar -n、iftop |
连接数、每秒收发 |
易错 性能排查最忌讳"盯着一个指标死磕"。负载高不一定是 CPU 忙——很可能在等磁盘 (wa) 或排队网络。正确做法是四个资源同时看一眼,先确定"到底谁忙"。
top:第一印象¶
top 是实时全貌,进入后按 P(CPU 排序)、M(内存排序)、q(退出):
top # 交互
top -bn1 | head -25 # 批处理单次输出,适合记到日志
%Cpu 一行的关键字段:us(用户态)、sy(系统态/内核)、id(空闲)、wa(等待磁盘 I/O,越大说明磁盘是瓶颈)、st(被宿主机偷走的,虚机才有)。
提示
wa(iowait)高是"磁盘慢"的典型信号。us高是应用吃 CPU,sy高是系统调用/内核忙(常见于频繁网络收发或文件读写)。
vmstat:采样看趋势¶
单次 top 是瞬间截图,vmstat 能连续采样看趋势(性能问题常是间歇性的):
vmstat 2 10 # 每 2 秒一次,共 10 次
procs ----memory---- ---swap-- ----io--- ---system--- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 ... ... ... 0 0 0 0 ... .. 20 10 68 2 0
关键列:r(运行队列,>CPU 核数即过载)、b(阻塞队列,>0 说明有 I/O 卡住)、wa(iowait)、bi/bo(每秒块读/写)、si/so(swap 换入/换出,非零即内存吃紧)。
易错
r是"排队等 CPU 的任务数",判断过载要除以核数(本机 4 核,r长期 >4 才算 CPU 饱和)。b长期非零则多半是磁盘 I/O 瓶颈,别误判成 CPU。
mpstat:CPU 用在哪¶
多核机器上某几核被打满而整体不高,用 mpstat -P 按核看:
mpstat -P ALL 2 # 每 2 秒输出每个核的状态
mpstat 2 # 所有核平均
易错 Node/PHP 应用大多是单线程,
mpstat -P ALL能看到"只有核 0 忙碌、其余空闲",这类无法靠加核解决,要加进程数(cluster)或拆服务。本机 Node 默认单进程,正是此理。
iostat:磁盘是否瓶颈¶
iostat 是磁盘 I/O 专项工具(sysstat 包,需要 apt install sysstat):
iostat -x 2 # 每 2 秒,列详细信息(含 %util、await)
iostat -xz 2 # -z 只显示有活动的设备,更干净
重点关注列:%util(磁盘繁忙百分比,接近 100 说明 I/O 饱和)、await(平均响应毫秒,越大越慢)、r/s/w/s(每秒读/写次)、rMB/s/wMB/s(吞吐)。
易错
%util=100并不一定代表"慢",它只说明磁盘一直在忙。真正的磁盘性能差参考await(单次 I/O 响应时间)。SSD 上await应个位数毫秒,机械盘可能几十毫秒;await持续过高说明排队严重。
sar:历史与定时采集¶
sar 来自 sysstat,能看某时段的历史(默认靠 cron 记录)——这正适合"问题发生在凌晨但你没在场"的场景:
sar -u # CPU 使用率
sar -r # 内存
sar -b # 块 I/O
sar -n DEV # 网络
sar -u 1 5 # 每 1 秒采样 5 次
# sysstat 会通过 cron 每天记录,默认 7 天;可查某天数据
sar -u -f /var/log/sysstat/sa06 # 找 06 号的历史文件
易错
sar的日/周/月数据需要/etc/cron.d/sysstat里的定时任务持续写入,默认保留 7 天。若用systemctl管理服务器,确认sysstat服务及 cron 正常,否则看不到历史。
长期监控:Prometheus + node-exporter¶
短时命令看不到的"缓慢爬升""深夜偶发",要交给监控。本机已部署 Prometheus 体系:
systemctl status prometheus # 时间序列数据库(9090)
systemctl status prometheus-node-exporter # 采集主机指标(9100)
ss -tlnp | grep 9090 # 确认 Prometheus 在监听
node-exporter 暴露大量主机指标(CPU、内存、磁盘、网络、文件描述符),Prometheus 定时抓取并落库,Grafana 画图、设告警。它的关键指标包括:
node_cpu_seconds_total—— CPU 使用;node_memory_MemAvailable_bytes—— 可用内存;node_filesystem_avail_bytes—— 可用磁盘;node_load1/5/15—— 平均负载。
易错
node-exporter默认绑定9100,若对外暴露需用防火墙限制来源(见第 8 章)。真实告警不要在 Prometheus 里写死一个"CPU>80"——要结合基线(比如irate计算瞬时速率)判断。这类规则属运维进阶,本章先建立"有监控、能看趋势"的意识。
性能基线:先知道"正常是多少"¶
性能监控的终极目标是建立基线。没有基线,任何数字都无参照。建议:
- 记录本机常态:空载
us%、id%、wa%,free的available,磁盘%util; - 用
sar/Prometheus 存历史,形成"正常区间"; - 异常来临对比基线,才能判断"是异常还是本来如此"。
# 日常随手记一条基线
echo "[$(date)] $(uptime) | $(free -h | awk 'NR==2{print $3}') used | $(iostat -x 1 1 | grep sda | awk '{print $14}') %util" >> /var/log/system_baseline.log
案例:Node 应用响应慢的排查¶
top -bn1 | head -20 # CPU/wa 一眼看谁忙
mpstat -P ALL 2 # 是否单核打满
free -h # 内存
vmstat 1 5 # r/b/si/so
iostat -x 2 # 是否磁盘瓶颈
ss -s # socket 概览(是否连接堆积)
若 us 接近 100 → 应用代码吃 CPU,去优化;若 wa 高 → 磁盘慢(换 SSD/加缓存);若 si/so 非零 → 内存吃紧。
易错点¶
- 只盯一个指标:四要素要同时看,确定瓶颈在谁。
r不除核数判断过载:本机 4 核,r>4才算 CPU 饱和。%util=100就判磁盘死:还要看await是否真的高。- 无基线不设告警:随手写死阈值会误报或漏报。
相关命令¶
top、htop、vmstat、mpstat、iostat、sar、iotop、ss、free、iftop、uptime。