服务器性能五维排查
服务器性能问题归结为四类资源瓶颈:CPU、内存、磁盘 IO、网络,外加容易被忽视的文件系统维度。 交叉验证是避免误判的关键——四个维度往往交织在一起。
快速定位:性能决策树
服务器慢 → vmstat 1 3
├─ r > CPU核数×2 + us高 → CPU瓶颈 → ps→top-Hp→jstack
├─ b > 0 → IO阻塞 → iostat→iotop
├─ si/so持续 → 内存不足 → free→找进程
└─ cs高 + sy高 → 上下文切换→ss→优化连接复用
Netflix 60 秒快速诊断法
来自 Netflix 性能工程团队的经验:登录服务器后前 60 秒按顺序执行标准命令组,快速定位瓶颈。
命令序列(60 秒按时间槽执行)
# 第 1~5s: uptime + dmesg -T | tail
# 第 6~15s: vmstat 1 5 + mpstat -P ALL 1 3
# 第 16~25s: pidstat 1 5
# 第 26~35s: iostat -xz 1 3 + free -m
# 第 36~45s: sar -n DEV 1 3 + sar -n TCP,ETCP 1 3
# 第 46~60s: top(按 P 键排序确认)
每个命令看什么
| 命令 | 一句话作用 | 关键指标 | 异常信号 |
|---|---|---|---|
uptime |
快速查看系统负载和运行时间 | load average 三个值 |
1 分钟远大于 5/15 分钟 → 问题刚爆发;15 分钟也高 → 已持续 |
dmesg -T \| tail |
最近内核报错 | OOM、磁盘错误、网络超时 | 出现 Out of memory 或 hung_task |
vmstat 1 5 |
系统整体运行状态 | r(运行队列)、si/so(内存交换) |
r > CPU 核数 → 进程堵了;si/so 非零 → 内存不够 |
mpstat -P ALL 1 3 |
每个 CPU 负载是否均衡 | 单个核 %CPU 接近 100% |
单核满 → 单线程热点;所有核满 → 流量/全局中断 |
pidstat 1 5 |
定位耗资源的进程 | %CPU、%MEM |
某进程 CPU 持续 300%+ → 可疑进程 |
iostat -xz 1 3 |
磁盘 IO 是否瓶颈 | await、%util |
await > 10ms → 磁盘变慢;%util 接近 100% → 磁盘忙不过来了 |
free -m |
内存使用情况 | available |
available 过低 → 内存不足 |
sar -n DEV 1 3 |
网卡流量是否异常 | rxkB/s、txkB/s |
突增/突降 |
sar -n TCP,ETCP 1 3 |
TCP 连接状态 | 重传率 | 重传异常升高 → 网络质量问题 |
top |
动态确认(最后用) | CPU/内存排序 | 按 P(CPU)或 M(内存)排序确认 |
详见 linux-server-load-case-study(附完整命令序列和案例解读)。
五维排查总览
| 维度 | 核心指标 | 核心工具 | 典型误判 |
|---|---|---|---|
| CPU | us/sy/id/wa, r 列, cs, si | top, vmstat, mpstat, pidstat | idle=0 ≠ CPU瓶颈(可能 IO wait) |
| 内存 | available, si/so, Swap | free, /proc/meminfo, slabtop | free少 ≠ 内存不足(Page Cache正常) |
| 磁盘 IO | %util, await, avgqu-sz | iostat, iotop, pidstat -d | util高 ≠ 磁盘慢(RAID/SSD可并行) |
| 网络 | estab, timewait, RetransSegs | ss, ip, ethtool, netstat -s | connect refused ≠ 网络问题(可能进程挂了) |
| 文件系统 | IUse%, 文件系统类型 | df -Th, tune2fs, df -i | 磁盘空间够 ≠ 能写文件(Inode耗尽) |
CPU 排查
vmstat 1 10 # r:运行队列, us/sy/id/wa, cs:上下文切换
mpstat -P ALL 1 5 # 每个核心使用率(排查负载不均)
pidstat -p <PID> 1 5 # 进程 CPU 分解
cat /proc/interrupts # 查看设备中断分布
关键判断:
- us 高 + 单进程 CPU 高 → 应用代码问题
- sy 高 + cs 高 → 上下文切换过多(检查短连接 / 系统调用)
- si 高 → 软中断压力(通常网络流量大)
- r > CPU 核心数 × 2 持续 → CPU 资源不足
详见 linux-load-average-guide(Load Average 解读与 D 状态排查)。
CPU 调优建议
taskset绑定关键进程到特定 CPU 核- nginx
worker_processes auto自动匹配核心数 - 数据库连接池别太大(增加上下文切换开销)
- 高 IO 场景开启 CPU
performance频率调节器
strace 快速诊断
当 pidstat 显示某进程 CPU 高但原因不明时,用 strace 看系统调用分布:
# 统计模式(开销可控,适合线上)
strace -p <PID> -c
# 运行几秒后 Ctrl+C,输出 write/read/stat/select 等调用次数和耗时占比
典型模式:
write调用多 → 怀疑日志写入或 IO 频繁,配合ls -l /proc/PID/fd/找出目标文件stat调用多 → 怀疑文件状态检查频繁(如日志轮转配置不当)select/poll调用多 → 怀疑网络 IO 或事件轮询
参见 cpu-spike-3-commands 获取完整的三命令排查法实战案例。
内存排查 (新)
不要看 free 列,要看 available 列。 Linux 把空闲内存用于 Page Cache,available 才是真正可用内存。
free -h # 重点看 available
cat /proc/meminfo # MemAvailable, SReclaimable, Swap*
vmstat 1 5 # 关注 si/so(swap in/out)
slabtop -s c | head -20 # 排查 Slab 内存泄漏
ps aux --sort=-%mem | head -11
dmesg | grep -i "out of memory\|killed process" # OOM 日志
可用性信号:
- available < total × 0.2 + swapfree 持续下降 → 内存压力
- si/so 持续不为 0 → 物理内存不够
- OOM Killer 启动 → 严重不足
- SUnreclaim 持续增长 → 可能内核内存泄漏
Java 特殊注意: JVM 内存 ≠ -Xmx。包含堆 + 元空间 + 直接内存 + Native。用 jcmd <PID> VM.native_memory。
内存调优建议
vm.swappiness默认 60 → 建议 10~20(减少主动使用 Swap)- Java:合理设置
-Xmx/-Xms,避免 JVM 吃光内存 - MySQL:
innodb_buffer_pool_size设为物理内存 60~70% - 容器环境:用 cgroup 限制单容器内存上限
- Transparent Huge Pages(THP)对某些数据库有负面影响,谨慎开启
磁盘 IO 排查
iostat -xz 1 5 # 核心工具:%util, await, avgqu-sz
iotop -o -b -n 10 # 只显示有 IO 的进程
pidstat -d 1 5 # 进程级 IO
判断标准(机械硬盘): util > 80% + await > 50ms → 磁盘饱和。avgqu-sz > 2 → 请求积压。 SSD/NVMe 不同: await > 10ms 才算异常,util 100% 可能是并发上限。
磁盘 IO 调优建议
- 日志和数据分盘存放,避免争抢 IO 带宽
- 数据库开启 O_DIRECT 绕过页缓存,减少双重缓存浪费
- IO 调度器:SSD 用
none(mq-deadline),HDD 用bfq vm.dirty_ratio/vm.dirty_background_ratio适当调大,让系统批量写盘- 高写入场景考虑 RAID 10 或 NVMe SSD 替代机械盘
网络排查
ss -s # 连接状态:estab, timewait
ip -s link show # 接口流量/丢包
netstat -s | grep -i "retransmit" # 重传统计
ethtool -S eth0 # 网卡级丢包(rx_dropped)
瓶颈类型:
- 流量接近带宽上限 → 带宽不足
- 大量 TIME_WAIT → 短连接未复用
- 重传率增长 → 网络质量差
- Ring Buffer 溢出(rx_dropped)→ IRQ 均衡或增大 Ring Buffer
- 端口号耗尽 → 调大 ip_local_port_range
生产验证的 TCP 参数
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 15 # FIN_WAIT2 超时(默认 60)
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
net.core.netdev_max_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
# 开启 TIME_WAIT 复用(不要用 tcp_tw_recycle,NAT 环境有 bug)
net.ipv4.tcp_tw_reuse = 1
网络调优建议
- 连接池复用 TCP,避免频繁创建销毁
- 内网服务间用 HTTP/2 多路复用
- 监控 TCP 重传率(
ss -ti),重传 > 3% 排查网络链路 - CLOSE_WAIT 异常 → 应用没正确关闭连接,检查连接池管理
详见 network-troubleshooting-order。
文件系统排查
文件系统是容易被忽视的第五个瓶颈维度。磁盘空间够 ≠ 能写文件(Inode 耗尽)。
关键命令
df -Th # 文件系统类型和使用率
df -i # Inode 使用率(小文件多时易踩坑)
tune2fs -m 1 /dev/sdb1 # ext4 保留块 5%→1%(数据分区)
mount -o remount,noatime /data # XFS 加 noatime,减少元数据写 IO
关键判断
- IUse% > 90% → Inode 即将耗尽(小文件密集场景预警)
- ext4 保留块默认 5%,对大分区浪费巨大
- XFS 大文件和高并发写入优于 ext4
- 所有分区应加
noatime,减少读文件时的元数据写入
调优建议
- 数据库和日志分区用 XFS
- 分区加
noatime挂载 - 定期
e2fsck(ext4)或xfs_scrub(XFS) - 小文件密集型场景用 tmpfs(放内存)
df -i定期监控 Inode,别等到 100% 才发现
实战流程模拟(60 秒演练)
以下模拟一次真实故障场景,展示如何在 60 秒内依次执行命令找出可疑进程。
① 登录后第一时间敲 uptime
输出:load average: 12.50, 3.20, 1.80 → 1 分钟负载 12.5(4 核 CPU),明显爆了,问题刚发生。
② 敲 vmstat 1 5
r 列连续 5 行都是 15 左右 → 运行队列远大于 CPU 核数,CPU 严重不够用。
si/so 都是 0 → 内存暂时没问题。
③ 敲 pidstat 1 5
输出中可见一个 java 进程(PID: 12345),%CPU 稳定在 300%+,%MEM 偏高 → 目标进程。
④ 敲 top 按 P 键排序确认
CPU 占用第一的就是 PID 12345,与 pidstat 一致。
⑤ 补充检查 iostat 和 sar
iostat -xz 1 3 和 sar -n DEV 1 3 → 磁盘和网卡都正常,排除 IO 和网络问题。
⑥ 留存证据
把关键输出存到文件:vmstat 1 10 > /tmp/vmstat.log,方便复盘。
一套操作下来刚好 60 秒,已找到可疑进程(PID 12345),排除了磁盘、网络、内存问题。后续用 jstack、strace 分析 Java 进程即可定位具体死循环或内存泄漏。
常见误区与救命贴士
| 误区 | 正确做法 |
|---|---|
| ❌ 一开始就敲 top | 先执行 uptime、dmesg、vmstat 等一次性输出命令,最后用 top 确认。top 默认 3 秒刷新会覆盖历史信息 |
| ❌ 用 history 翻命令 | 紧急情况下翻历史太浪费时间。把 10 条命令记熟,或提前写成脚本应急执行 |
| ✅ 输出重定向到文件 | pidstat 1 5 > /tmp/pidstat.log,哪怕系统重启也有故障快照用于复盘 |
| ⚠️ 系统卡得敲不了命令 | 说明问题极其严重,直接重启或从带外管理口登录,别浪费时间 |
性能瓶颈速查表
从症状快速判断瓶颈方向,确定优先执行的排查命令:
| 症状 | 可能瓶颈 | 优先排查 | 关键指标 |
|---|---|---|---|
| 服务器响应慢、load average 高但 CPU 空闲 | IO 瓶颈 / 大量 D 状态进程 | iostat -xz 1 3 → ps aux \| grep D |
wa > 20%, b > 0 |
| CPU us 持续 > 80% | CPU 密集型(应用代码) | top → pidstat -p <PID> 1 5 |
us 高, sy 正常 |
| CPU sy 持续 > 30% | 内核/系统调用/中断过量 | mpstat -P ALL 1 3 → cat /proc/softirqs |
sy 高, cs 极高, si 高 |
| free 少 + si/so 持续非零 | 内存不足 | free -m → ps aux --sort=-%mem \| head |
available < 20%, si/so > 0 |
| 磁盘 util 接近 100% | 磁盘吞吐打满 | iostat -xz 1 → iotop |
%util > 95%, await > 10ms |
| 磁盘 await > 50ms(HDD) | 磁盘响应慢 | iostat -xz 1 → 检查磁盘健康 |
await 高, 但 util 不高 → 磁盘慢 |
| TIME_WAIT 连接数万级 | 短连接风暴 | ss -s → netstat -s \| grep -i retrans |
TIME-WAIT > 30000, 重传率 > 1% |
| 网卡 rx_dropped 持续增长 | 环形缓冲区溢出 | ethtool -S eth0 \| grep drop → ethtool -g eth0 |
rx_dropped 持续增长 |
| CPU steal > 10% | 宿主机超卖 | 联系云平台 | %steal 高,其他指标正常 |
| 单核 100% 其他核空闲 | 单线程热点 | pidstat -t -p <PID> 1 5 → top -H |
单核满,其他核空闲 |
| swap 使用持续增长 | 内存泄漏 | ps aux --sort=-%mem → 观察进程内存趋势 |
swpd 持续上升,si/so 持续 |
关联页面
| 页面 | 关联点 |
|---|---|
| linux-load-average-guide | Load Average 解读 + CPU 排查五步法 |
| linux-kernel-tuning-production | sysctl 系统参数详解(内核调优) |
| fullstack-performance-troubleshooting | 应用层性能排障方法论(Nginx→DB) |
| network-troubleshooting-order | 网络连通性排障七步法 |
| nginx-config-pitfalls | 踩坑点四 upstream keepalive / 踩坑点八 worker_rlimit_nofile |
| node-troubleshooting | K8s Node 资源压力排查 |
| linux-disk-space-troubleshooting | Linux 磁盘空间排查 8 命令(df/du/lsof/journalctl) |
| linux-server-load-case-study | 服务器负载过高排查案例 + Netflix 60 秒法 |
| cpu-spike-troubleshooting-guide | 完整 CPU 排查方法论(整机→进程→线程→调用栈四层定位) |
| linux-disk-io-tuning | Linux 磁盘 IO 调优完整指南(iostat/iotop/fio/脏页/调度器/案例) |
| linux-memory-management-deep-dive | Linux 内存管理深潜(Buffer/Cache/Page Cache/Slab/回收/OOM/cgroup v2) |
| amazon-advertising-types | 亚马逊广告完全指南(五大类型 + PPC 关键词卡位术) |
| linux-api-performance-tuning-case-study | Linux 系统调优实战(接口 500ms→100ms 全复盘) |
| ops-automation-scripts | 运维自动化脚本 5 件套 — 健康巡检脚本与告警阈值互补 |
| linux-essential-commands-reference | Linux 30 个高频命令速查(vmstat/free/iostat 等监控命令一览) |
| journalctl-log-tracking-guide | journalctl 日志实时监控指南 |
| tcp-connection-attack-vs-bug | TCP 连接数爆表排查:攻击 vs Bug |
| linux-hardware-info-and-ops-guide | Linux 硬件信息查询与软件管理命令速查 — CPU/内存/磁盘/网络/主板全覆盖 |
| linux-load-high-cpu-low-troubleshooting | Linux Load 高但 CPU 低的排查思路 — 从现象确认到根因定位的系统化诊断流程(含 vm |
| nfs-troubleshooting-sop | NFS 故障排查 SOP — 7 步排查法 / 6 类故障 / 4 大实战案例 / 生产最佳实践 |
| linux-kernel-tuning-guide | Linux 高并发内核优化手册 — 文件句柄/网络/内存/安全四维调优(含 sysctl 配置模板) |
| linux-perf-troubleshooting-handbook | Linux 服务器性能排查实战手册 — 60 秒快速摸底/4 大瓶颈排查/3 个实战案例/监控阈值/ |
| jvm-container-oom-offheap-troubleshooting | JVM 堆外内存(DirectByteBuffer/Metaspace/线程栈)导致容器 OOMKi |
| linux-filesystem-directory-structure-guide | Linux FHS 文件系统目录结构详解 — 含各目录用途、运维排查路径速查、磁盘分区方案 |
| linux-raid-lvm-basics-guide | Linux RAID 与 LVM 基础入门 — RAID 0/1/5/6/10 级别对比、LVM 分 |
| k8s-java-memory-tuning-production-guide | Kubernetes 下 Java 内存调优完整指南 — 内存预算模型、生产参数配置、四层诊断流程、 |
| linux-disk-inspection-tools-guide | 磁盘排查工具实战指南 — iostat 阈值解读/smartctl 健康诊断/lsscsi 设备列表 |
| online-troubleshooting-checklist | 四维排查速查清单(CPU/磁盘/内存/网络 + Java 工具 jstack/jmap/jstat/tcpdump) |
告警阈值
| 指标 | 警告 | 严重 |
|---|---|---|
| CPU 使用率 | > 80%/5min | > 95%/2min |
| Load Average | > 核心数×0.7 | > 核心数×1.5 |
| 可用内存 | < 20% | < 10% |
| 磁盘 await (HDD) | > 50ms | > 100ms |
| 磁盘 util | > 80% | > 95% |