主题
性能监控
"服务器变慢了"——这是最模糊却最常见的运维问题。本篇给你一套从现象到根因的完整排查框架,以及 CPU、内存、磁盘 IO、网络四个维度的监控工具和定位方法。
方法论:排故四步法
1. 确定症状 → "什么操作变慢了?" 确认是 CPU 打满 / 内存不够 / 磁盘 IO / 网络延迟
2. 明确时间 → "什么时候开始的?" 看监控图,找到拐点
3. 横向对比 → "所有请求都慢还是只某个接口慢?"
4. 逐层下钻 → 先看整机 → 再看进程 → 最后看线程/调用栈全局概况:先看这 4 条命令
出问题时,不要上来就 deep dive,先用这几条做"体检":
bash
# 1. 系统负载
uptime
# 输出:12:53:30 up 30 days, 2:15, 3 users, load average: 0.52, 0.38, 0.35
# load average 的三个数分别是 1min/5min/15min 平均负载
# 判断标准:负载 ≈ CPU 核心数 → 刚好;负载 > 核心数 → 有过载趋势;负载 > 2×核心数 → 严重过载
# 2. CPU + 内存快照
top -bn1 | head -20
# 3. 磁盘 IO 快照
iostat -x 1 3
# 4. 网络流量概况
sar -n DEV 1 3CPU 篇
top / htop
bash
top
# 按 1 → 展开每个 CPU 核心
# 按 P → 按 CPU 排序
# 按 c → 显示完整命令行top 头部解读:
%Cpu(s): 2.3 us, 0.5 sy, 0.0 ni, 97.0 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st
用户态 内核态 调整优先级 空闲 等待IO 硬中断 软中断 虚拟机偷走CPU 指标含义
- us(user)高 → 应用程序在吃 CPU,找哪个进程
- sy(system)高 → 系统调用频繁或内核有瓶颈
- wa(iowait)高 → CPU 在等磁盘 IO,瓶颈在磁盘不是 CPU
- id(idle)高 → CPU 闲,不忙
mpstat — 每核 CPU 详情
bash
# 需安装 sysstat
sudo apt install sysstat
mpstat -P ALL 1 # 每秒输出所有核心的 CPU 使用率
# 看哪个核心特别忙(单线程程序常见)perf — 找出 CPU 热点
bash
# 粗略定位:哪个函数花了最多 CPU
sudo perf top
# 或采集一段时间后分析
sudo perf record -p <PID> -g -- sleep 10
sudo perf report内存篇
free — 内存概览
bash
free -h
# total used free shared buff/cache available
# Mem: 7.8G 3.2G 1.5G 200M 3.1G 4.2G
# Swap: 2.0G 100M 1.9G
# 关键看 available,不是 free!
# Linux 会积极缓存文件(buff/cache),free 很少是正常的
# available = free + 可回收的缓存 = 新程序能用的内存free 很低别慌
Linux 的设计哲学是「空闲内存是浪费」。buff/cache 里的内存随时可回收给应用使用。只有 available 很低(< 10% 总量)才说明内存紧张。
vmstat — 内存活动监控
bash
vmstat 1
# si/so 列:swap in / swap out
# si > 0 或 so > 0 说明在换入换出 → 内存不足,可能在颠簸(thrashing)OOM Killer
bash
# 查看 OOM 历史
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"
journalctl -k | grep -i oom
# OOM 打分:分数越高越容易被杀
cat /proc/<PID>/oom_score
# 保护关键进程(调低 oom_score_adj,越小越不容易被杀)
echo -1000 > /proc/<PID>/oom_score_adj
# 注意:oom_score_adj 范围是 -1000 到 1000,-1000 完全排除出 OOM 候选
# oom_adj 是旧版接口(Linux <2.6.36),现已废弃,一律用 oom_score_adj磁盘 IO 篇
iostat — IO 性能核心工具
bash
iostat -x 1
# 关键列:
# r/s, w/s: 每秒读写次数
# rkB/s, wkB/s: 每秒读写的 KB 数
# await: I/O 请求平均等待时间(ms),>10ms 说明有压力
# svctm: I/O 请求平均服务时间
# %util: 磁盘使用率,接近 100% 说明磁盘是瓶颈(但对 SSD 不完全适用)iotop — 看谁在 IO
bash
# 需安装
sudo apt install iotop
sudo iotop
# 类似 top,但按磁盘读写量排序
# 按 o 只显示有 IO 活动的进程快速定位 IO 问题的命令
bash
# 哪个进程在疯狂写盘?
sudo iotop -bon1 | head -20
# 磁盘延迟?
iostat -x 1 | awk 'NR>3 && $NF>0 {print "Device:",$1,"await:",$10"ms","util:",$NF"%"}'网络篇
iftop — 实时网络流量
bash
# 需安装
sudo apt install iftop
sudo iftop -i eth0
# 显示每对连接的实时流量nload — 更直观的流量图
bash
sudo apt install nload
nload eth0
# 显示进出流量的 ASCII 图表,一目了然sar — 历史网络统计
bash
# 查看今天的网络历史(sysstat 默认每 10 分钟记录一次)
sar -n DEV
sar -n DEV -f /var/log/sysstat/sa26 # 看 7月26日
# TCP 连接统计
sar -n TCP,ETCP 1 5综合工具
glances(强烈推荐)
bash
pip install glances
glances
# 一屏显示 CPU/内存/IO/网络/进程/传感器温度
# 彩色高亮告警,新手上手最快dstat(万金油)
bash
sudo apt install dstat
dstat -c -m -d -n --top-cpu --top-mem 1 10
# -c: CPU -m: 内存 -d: 磁盘 -n: 网络
# --top-cpu: CPU 占用 top5 --top-mem: 内存 top5实战:"服务器变慢了" 完整排查流程
bash
# === 第一步:全局体检 ===
uptime # 看负载是否过高
free -h # 看内存是否耗尽
df -h # 看磁盘是否满了
dmesg | tail -30 # 看内核是否在报错(硬件/OOM)
# === 第二步:定位瓶颈类型 ===
# 打开 top,看各维度:
# %Cpu wa 高 → IO 瓶颈
# %Cpu us 高 → CPU 瓶颈
# available 内存低 → 内存瓶颈
# load average 高但 CPU idle 也高 → IO 瓶颈(CPU 在等磁盘)
# === 第三步:深入对应的维度 ===
# 场景A:CPU 高
top -o %CPU # 找最高 CPU 进程
perf top # 看函数级热点
# 是正常业务增长 → 扩容。是死循环 → 重启服务。是 GC → 调 JVM
# 场景B:内存不足
ps aux --sort=-%mem | head -10 # 找内存大户
cat /proc/<PID>/smaps | grep Pss | awk '{sum+=$2} END {print sum/1024 " MB"}'
# 是内存泄漏 → 重启(临时),改代码(根治)。是正常增长 → 扩容
# 场景C:IO 慢
iostat -x 1 3 # 看 await 和 %util
sudo iotop -o # 找 IO 大户
# 大量随机小写 → 上 SSD。顺序大读写 → 正常的备份/日志,调整调度时间
# 场景D:网络慢
ping -c 10 目标IP | tail -1 # 看延迟和丢包
mtr 目标IP -r -c 10 # 看是哪一跳开始丢包
ss -s # 看连接数是否异常
# TIME_WAIT 堆积 → 调内核参数 net.ipv4.tcp_tw_reuse
# SYN_RECV 堆积 → 可能被 SYN flood 攻击防止性能退化:基准测试与监控
bash
# CPU 基准
sysbench cpu --threads=$(nproc) run
# 磁盘 IO 基准
sysbench fileio --file-test-mode=rndrw prepare
sysbench fileio --file-test-mode=rndrw run
sysbench fileio --file-test-mode=rndrw cleanup
# 网络吞吐
iperf3 -s # 服务端
iperf3 -c 服务器IP # 客户端生产环境性能监控清单
- CPU 使用率 > 80% 告警(持续 5 分钟)
- 内存 available < 10% 告警
- 磁盘使用率 > 85% 告警
- 磁盘 await > 20ms 告警
- 网络丢包率 > 1% 告警
- 关键接口响应时间 > 阈值告警
生产环境经验
- 建基线:系统正常时的 CPU/内存/IO 数值要心中有数,异常时才看得出差异
- 不要只看平均值:看 P99/P95 延迟和峰值负载,平均值掩盖问题
- 监控要持续:手动
top只能看现在,用 Prometheus + Grafana 看趋势 - 预热:JVM/Go 等服务刚启动时性能可能较低(JIT 编译、连接池建立),等几分钟再看
- 负载测试:上线前用 wrk/ab/locust 压测,找到系统的容量上限
🎯 本章要点
- load average 三个值:1/5/15 分钟平均负载
- 排故顺序:明确症状 → 时间范围 → 横向对比 → 逐层下钻
top -bn1非交互模式适合脚本抓取
加载练习题中...