关注「Raymond运维」公众号,并设为「星标」,也可以扫描底部二维码加入群聊,第一时间获取最新内容,不再错过精彩内容。
Linux系统性能瓶颈分析:CPU、内存、磁盘、网络四维排查法
1. 适用场景 & 前置条件
| |
|---|
| 服务器响应慢、应用卡顿、负载高、OOM 频繁、数据库慢查询、网络丢包 |
| RHEL/CentOS 7.9+ 或 Ubuntu 20.04+ |
| Linux Kernel 3.10+(推荐 5.10+ 支持更多性能监控特性) |
| sysstat 11.0+、perf 4.0+、iotop 0.6+、nethogs 0.8+ |
| |
| |
| 熟悉 Linux 进程管理、文件系统、网络协议栈、内核参数调优 |
2. 反模式警告(何时不适用)
⚠️ 以下场景不推荐仅使用本方案:
- 1. 应用层逻辑问题:代码死循环、内存泄漏、算法复杂度高(应结合代码 profiling 工具如 pprof/py-spy)
- 2. 分布式系统瓶颈:微服务调用链慢、消息队列积压(需使用 APM 工具如 SkyWalking/Jaeger)
- 3. 数据库内部问题:索引缺失、查询计划不优(需数据库专用工具如 pt-query-digest/pgBadger)
- 4. 硬件故障:磁盘坏道、内存条损坏、网卡故障(需硬件诊断工具)
- 5. 云服务限流:云主机突发性能实例耗尽积分、云数据库 IOPS 限额(查看云厂商监控)
替代方案对比:
| | |
|---|
| Go pprof / Python py-spy / Java JProfiler | |
| Jaeger / Zipkin / SkyWalking | |
| pt-query-digest / EXPLAIN ANALYZE | |
| | |
| SystemTap / eBPF (bpftrace) | |
3. 环境与版本矩阵
| | | |
|---|
| RHEL 8.7+ / CentOS Stream 9 | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
版本差异说明:
- • Linux 5.10+ 支持更多 eBPF 特性(bpftrace 工具依赖)
- • sysstat 12.0+ 支持 JSON 格式输出(便于 Prometheus 采集)
4. 阅读导航
📖 建议阅读路径:
快速上手(15分钟):→ 章节5(快速清单)→ 章节6(实施步骤 Step 1-4)→ 章节12(一键诊断脚本)
深入理解(60分钟):→ 章节7(最小必要原理)→ 章节6(实施步骤完整版)→ 章节11(最佳实践)→ 章节13(扩展阅读)
故障排查:→ 章节9(常见瓶颈对照表)→ 章节6.5-6.8(具体调优步骤)
5. 快速清单(Checklist)
- • [ ] 安装 sysstat 工具集(
yum install sysstat / apt install sysstat) - • [ ] 安装 perf 工具(
yum install perf / apt install linux-tools-$(uname -r)) - • [ ] 安装 iotop / nethogs(
yum install iotop nethogs) - • [ ] 启用 sar 数据采集(
systemctl enable --now sysstat)
- • [ ] 查看整体 CPU 使用率(
top / htop) - • [ ] 查看进程级 CPU 占用(
ps aux --sort=-%cpu | head -20) - • [ ] 分析 CPU 上下文切换(
vmstat 1 / pidstat -w 1) - • [ ] 查看 CPU 中断(
cat /proc/interrupts,mpstat -P ALL 1) - • [ ] CPU 火焰图分析(
perf record + FlameGraph)
- • [ ] 查看内存整体使用(
free -h / vmstat 1) - • [ ] 查看进程内存占用(
ps aux --sort=-%mem | head -20) - • [ ] 分析内存泄漏(
valgrind --leak-check=full) - • [ ] 查看 SWAP 使用(
swapon -s / vmstat 1) - • [ ] OOM Killer 日志(
dmesg | grep -i oom)
- • [ ] 查看磁盘 IO 统计(
iostat -x 1) - • [ ] 查看进程 IO 占用(
iotop -o) - • [ ] 分析磁盘慢查询(
iotop -P -a 累积模式) - • [ ] 检查文件系统缓存(
cat /proc/meminfo | grep -i cache) - • [ ] 磁盘健康检查(
smartctl -a /dev/sda)
- • [ ] 查看网络连接状态(
ss -s / netstat -s) - • [ ] 分析丢包与重传(
netstat -s | grep -i retrans) - • [ ] TCP 连接队列(
ss -lnt 查看 Send-Q / Recv-Q)
6. 实施步骤(核心内容)
性能瓶颈分析四维模型
分析思路:
性能问题出现 ↓第一步:定位瓶颈维度(CPU/内存/磁盘/网络) ├─ 使用 top/htop 快速概览系统状态 ├─ 查看 Load Average(1分钟/5分钟/15分钟负载) └─ 使用 dstat 同时监控四维指标 ↓第二步:针对性深入分析 ├─ CPU 瓶颈 → 查看进程、线程、上下文切换、中断 ├─ 内存瓶颈 → 查看 RSS/VSZ、缓存、SWAP、OOM ├─ 磁盘瓶颈 → 查看 IOPS、吞吐量、IO 等待、文件系统 └─ 网络瓶颈 → 查看带宽、连接数、丢包率、延迟 ↓第三步:优化与验证 └─ 应用调优措施 → 持续监控 → 对比优化前后指标
关键指标阈值:
Step 1: CPU 维度排查
◆ 1.1 查看整体 CPU 使用率
# 实时监控 CPU 使用(刷新间隔 1 秒)top -d 1# 关键指标解读:# %Cpu(s): 14.3 us, 2.7 sy, 0.0 ni, 82.0 id, 0.7 wa, 0.0 hi, 0.3 si, 0.0 st# us (user): 用户态 CPU 占用(应用程序)# sy (system): 内核态 CPU 占用(系统调用、中断)# ni (nice): 低优先级进程 CPU 占用# id (idle): 空闲 CPU(理想 > 30%)# wa (iowait): IO 等待 CPU(> 10% 表示磁盘瓶颈)# hi (hardware interrupt): 硬件中断 CPU(> 5% 异常)# si (software interrupt): 软件中断 CPU(网络处理)# st (steal): 虚拟机被宿主机窃取的 CPU(云主机关注,> 10% 表示资源竞争)# 使用 htop(更直观的交互式工具)htop# 按键说明:# F2: 设置显示选项# F3: 搜索进程# F4: 过滤进程# F5: 树状显示# F6: 排序(CPU/MEM/TIME)# F9: 杀死进程# F10: 退出
判断 CPU 瓶颈:
# 查看 Load Averageuptime# 输出示例:# 10:30:01 up 15 days, 3:45, 2 users, load average: 4.50, 3.80, 2.10# 解读:# - 1 分钟负载:4.50(短期突发)# - 5 分钟负载:3.80(中期趋势)# - 15分钟负载:2.10(长期趋势)# 判断标准:Load Average / CPU 核心数 > 1.0 表示 CPU 不足# 查看 CPU 核心数grep -c ^processor /proc/cpuinfo# 输出:4(4 核心)# 结论:4.50 / 4 = 1.125 > 1.0(CPU 接近饱和)
◆ 1.2 查看进程级 CPU 占用
# 按 CPU 使用率排序查看前 20 个进程ps aux --sort=-%cpu | head -20# 输出示例:# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND# mysql 1234 85.3 5.2 2456784 524288 ? Ssl Jan10 1250:30 /usr/sbin/mysqld# java 5678 45.2 12.3 4567890 1234567 ? Sl Jan09 850:15 java -jar app.jar# nginx 9012 8.5 0.3 125000 32000 ? S Jan08 45:20 nginx: worker# 持续监控单个进程 CPU(每秒刷新)pidstat -p 1234 1# 输出示例:# 10:30:01 UID PID %usr %system %guest %wait %CPU CPU Command# 10:30:02 27 1234 75.00 10.00 0.00 0.00 85.00 2 mysqld# 10:30:03 27 1234 78.00 9.00 0.00 0.00 87.00 2 mysqld# 查看多线程程序的线程 CPU 使用top -H -p 1234# -H: 显示线程# -p: 指定进程 PID
◆ 1.3 分析 CPU 上下文切换
原理: 上下文切换过多会导致 CPU 浪费在进程切换而非实际计算
# 查看系统级上下文切换速率vmstat 1# 输出示例:# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----# r b swpd free buff cache si so bi bo in cs us sy id wa st# 4 0 0 512000 102400 1024000 0 0 0 10 8500 25000 60 15 25 0 0# 3 1 0 510000 102400 1024000 0 0 0 50 8600 28000 65 18 17 0 0# 关键列:# r: 运行队列长度(等待 CPU 的进程数,> CPU 核心数表示 CPU 不足)# b: 不可中断睡眠进程数(通常是 IO 等待,> 0 表示磁盘瓶颈)# in: 每秒中断次数(interrupts)# cs: 每秒上下文切换次数(context switches)# 正常值:cs < 10000,> 100000 表示异常# 查看进程级上下文切换pidstat -w -p 1234 1# 输出示例:# 10:30:01 UID PID cswch/s nvcswch/s Command# 10:30:02 27 1234 150.00 8500.00 mysqld# cswch/s: 自愿上下文切换(进程主动让出 CPU,如 IO 等待)# nvcswch/s: 非自愿上下文切换(时间片用完被强制切换,> 1000 表示 CPU 竞争激烈)
优化措施:
- • nvcswch/s 过高 → CPU 核心数不足,考虑升级或迁移部分进程
- • cswch/s 过高 → IO 密集型应用,优化磁盘性能或使用异步 IO
◆ 1.4 查看 CPU 中断
# 查看硬件中断统计cat /proc/interrupts# 输出示例(部分):# CPU0 CPU1 CPU2 CPU3# 0: 150 0 0 0 IO-APIC 2-edge timer# 8: 1 0 0 0 IO-APIC 8-edge rtc0# 9: 0 0 0 0 IO-APIC 9-fasteoi acpi# 16: 25000000 30000000 28000000 27000000 IO-APIC 16-fasteoi eth0# 17: 5000000 6000000 5500000 5300000 IO-APIC 17-fasteoi ahci[0000:00:1f.2]# 关注点:# - eth0(网卡中断)数值过大 → 网络流量高或网卡驱动问题# - ahci(磁盘中断)数值过大 → 磁盘 IO 频繁# 查看软中断(softirq)watch -d -n 1 'cat /proc/softirqs'# 按 CPU 查看中断分布mpstat -P ALL 1# 输出示例:# 10:30:01 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle# 10:30:02 AM all 60.25 0.00 15.00 0.75 0.50 3.50 0.00 0.00 0.00 20.00# 10:30:02 AM 0 65.00 0.00 18.00 1.00 1.00 5.00 0.00 0.00 0.00 10.00# 10:30:02 AM 1 58.00 0.00 14.00 0.50 0.30 2.20 0.00 0.00 0.00 25.00# %irq + %soft > 10% 表示中断处理消耗过多 CPU
◆ 1.5 CPU 火焰图分析(高级)
# 安装 perf 工具# RHEL/CentOSyum install perf# Ubuntu/Debianapt install linux-tools-$(uname -r) linux-tools-generic# 采集 CPU 性能数据(采样 30 秒)perf record -F 99 -a -g -- sleep 30# -F 99: 采样频率 99Hz# -a: 所有 CPU# -g: 记录调用栈# 输出:perf.data 文件# 查看采样报告perf report# 生成火焰图(需安装 FlameGraph 工具)git clone https://github.com/brendangregg/FlameGraph.gitperf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > cpu-flamegraph.svg# 在浏览器中打开 cpu-flamegraph.svg# 宽度 = CPU 时间占比,高度 = 调用栈深度# 点击可交互查看具体函数耗时
Step 2: 内存维度排查
◆ 2.1 查看整体内存使用
# 查看内存使用概览free -h# 输出示例:# total used free shared buff/cache available# Mem: 15Gi 8.5Gi 1.2Gi 500Mi 5.8Gi 6.0Gi# Swap: 8.0Gi 2.0Gi 6.0Gi# 关键指标:# total: 物理内存总量# used: 已使用内存(包含应用 + 缓存)# free: 真正空闲内存(通常很小,正常现象)# buff/cache: 文件系统缓存与缓冲区(可被释放)# available: 可用内存(free + 可释放的 cache)★ 重点关注# Swap used: SWAP 使用量(> 0 表示内存不足,> 10% 物理内存表示严重不足)# 实时监控内存变化vmstat 1# 输出示例:# 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 2048000 1200000 102400 5800000 0 10 0 20 8500 25000 60 15 25 0 0# 关键列:# swpd: SWAP 已使用量(字节)# free: 空闲内存# buff: 缓冲区内存# cache: 页缓存内存# si: 从 SWAP 读入内存的速率(KB/s)(> 0 表示正在使用 SWAP)# so: 写入 SWAP 的速率(KB/s)(> 0 表示内存压力大)
判断内存瓶颈:
# 计算内存使用率awk '/MemTotal/ {total=$2} /MemAvailable/ {avail=$2} END {printf "Memory Usage: %.2f%%\n", (total-avail)/total*100}' /proc/meminfo# 输出:Memory Usage: 62.50%# < 80%: 正常# 80-90%: 警告# > 90%: 严重(可能触发 OOM Killer)
◆ 2.2 查看进程内存占用
# 按内存使用排序查看前 20 个进程ps aux --sort=-%mem | head -20# 输出示例:# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND# mysql 1234 35.3 25.2 4567890 2567890 ? Ssl Jan10 450:30 /usr/sbin/mysqld# java 5678 15.2 18.3 6789012 1867890 ? Sl Jan09 250:15 java -jar app.jar# 关键列:# VSZ (Virtual Memory Size): 虚拟内存大小(包含共享库、未分配页)# RSS (Resident Set Size): 实际物理内存占用(重点关注)★# 查看进程详细内存映射pmap -x 1234# 输出示例:# Address Kbytes RSS Dirty Mode Mapping# 0000000000400000 1024 1024 0 r-x-- mysqld# 00007f8a5c000000 65536 32768 16384 rw--- [heap]# 00007f8a60000000 262144 131072 0 r---- /usr/lib/mysql/plugin/auth_socket.so# 查看进程内存详细统计cat /proc/1234/status | grep -E "VmSize|VmRSS|VmSwap"# 输出示例:# VmSize: 4567890 kB # 虚拟内存# VmRSS: 2567890 kB # 物理内存# VmSwap: 150000 kB # 被 SWAP 的内存(> 0 表示内存不足)
◆ 2.3 分析内存泄漏
# 持续监控进程内存增长趋势whiletrue; dodate ps aux | grep mysqld | grep -v grep | awk '{print "RSS: " $6 " KB"}'sleep 60done# 输出示例:# 2025-01-15 10:30:00# RSS: 2567890 KB# 2025-01-15 10:31:00# RSS: 2598765 KB # 增长 30MB# 2025-01-15 10:32:00# RSS: 2632456 KB # 持续增长 → 可能内存泄漏# 使用 valgrind 检测内存泄漏(开发/测试环境)valgrind --leak-check=full --log-file=valgrind.log ./your_app# 生产环境使用 pmap 对比内存映射变化pmap 1234 > pmap_before.txt# 等待 10 分钟pmap 1234 > pmap_after.txtdiff pmap_before.txt pmap_after.txt# 查找持续增长的内存段([heap] 或匿名映射)
◆ 2.4 查看 SWAP 使用与优化
# 查看 SWAP 分区信息swapon -s# 输出示例:# Filename Type Size Used Priority# /dev/sda2 partition 8388604 2048000 -2# 查看 SWAP 使用详情cat /proc/meminfo | grep -i swap# 输出示例:# SwapTotal: 8388604 kB# SwapFree: 6340604 kB# SwapCached: 1000 kB # 被缓存的 SWAP 页# 调整 SWAP 倾向性(临时生效)# vm.swappiness: 0-100,默认 60# 0: 尽量不使用 SWAP(除非内存极度不足)# 10: 推荐值(优先使用内存)# 60: 系统默认(平衡内存与 SWAP)# 100: 积极使用 SWAPsysctl vm.swappiness=10# 永久生效(/etc/sysctl.conf)echo"vm.swappiness = 10" >> /etc/sysctl.confsysctl -p# 清空 SWAP(释放被交换出的内存,需谨慎)# 前提:确保物理内存充足swapoff -a && swapon -a
◆ 2.5 OOM Killer 日志分析
# 查看 OOM Killer 历史记录dmesg | grep -i "out of memory"# 输出示例:# [1234567.890123] Out of memory: Killed process 5678 (java) total-vm:6789012kB, anon-rss:1867890kB, file-rss:0kB, shmem-rss:0kB# [1234568.901234] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=java,pid=5678,uid=1000# 解读:# - Killed process 5678 (java): 被杀死的进程# - total-vm: 虚拟内存总量# - anon-rss: 匿名内存(堆、栈)# - OOM Score: 每个进程有 oom_score(越高越容易被杀)# 查看进程 OOM Scorecat /proc/1234/oom_score# 输出:850(0-1000,数值越大越容易被 OOM Killer 选中)# 调整进程 OOM Score(降低被杀优先级)echo -1000 > /proc/1234/oom_score_adj# -1000 到 1000:-1000 = 永不被杀(慎用),1000 = 优先被杀# 查看系统内存分配策略cat /proc/sys/vm/overcommit_memory# 0: 启发式过量分配(默认)# 1: 允许过量分配(不推荐)# 2: 禁止过量分配(严格模式)
Step 3: 磁盘 IO 维度排查
◆ 3.1 查看磁盘 IO 统计
# 实时监控磁盘 IO(每秒刷新)iostat -x 1# 输出示例:# Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util# sda 150.00 800.00 6000.00 32000.00 0.00 5.00 0.00 0.62 12.50 45.20 3.50 40.00 40.00 8.50 95.60# sdb 10.00 20.00 400.00 800.00 0.00 0.00 0.00 0.00 2.30 3.50 0.05 40.00 40.00 1.20 3.60# 关键列:# r/s, w/s: 每秒读写次数(IOPS)# rkB/s, wkB/s: 每秒读写数据量(吞吐量)# r_await, w_await: 平均 IO 等待时间(ms)(< 20ms 正常,> 50ms 慢)# %util: 磁盘利用率(> 80% 表示 IO 瓶颈)★ 重点关注# aqu-sz: 平均队列长度(> 1 表示 IO 排队)# 判断 IO 瓶颈:# - %util > 80% 且 r_await / w_await > 20ms → 磁盘性能不足# - IOPS (r/s + w/s) 接近硬件上限:# - HDD: 100-200 IOPS# - SATA SSD: 50000-90000 IOPS# - NVMe SSD: 200000-500000 IOPS
◆ 3.2 查看进程 IO 占用
# 实时查看 IO 占用最高的进程iotop -o# -o: 仅显示有 IO 的进程# -P: 显示进程而非线程# -a: 累积 IO 统计# 输出示例:# Total DISK READ : 12.50 M/s | Total DISK WRITE : 32.00 M/s# Actual DISK READ: 10.20 M/s | Actual DISK WRITE: 30.50 M/s# TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND# 1234 be/4 mysql 8.50 M/s 25.00 M/s 0.00 % 85.30 % mysqld --defaults-file=/etc/my.cnf# 5678 be/4 www-data 3.20 M/s 6.50 M/s 0.00 % 12.50 % nginx: worker process# 查看进程累积 IO 统计pidstat -d -p 1234 1# 输出示例:# 10:30:01 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command# 10:30:02 27 1234 8500.00 25000.00 0.00 85 mysqld# kB_rd/s: 每秒读取数据量# kB_wr/s: 每秒写入数据量# iodelay: IO 延迟(时钟周期)
◆ 3.3 分析文件系统缓存
# 查看页缓存统计cat /proc/meminfo | grep -iE "cached|buffers|dirty|writeback"# 输出示例:# Buffers: 102400 kB # 块设备缓冲区# Cached: 5800000 kB # 页缓存(文件内容)★# SwapCached: 1000 kB# Dirty: 250000 kB # 脏页(已修改未写入磁盘)# Writeback: 5000 kB # 正在回写的脏页# 关键指标:# Dirty > 1GB → 大量脏页未刷盘,可能突发 IO 高峰# Writeback 持续 > 100MB → 磁盘写入慢,检查磁盘性能# 手动释放页缓存(测试用,生产环境慎用)# 1: 释放页缓存# 2: 释放 dentries 和 inodes# 3: 释放页缓存、dentries 和 inodesecho 3 > /proc/sys/vm/drop_caches# 调整脏页刷盘阈值(/etc/sysctl.conf)vm.dirty_ratio = 10 # 脏页达到物理内存 10% 时阻塞写入(默认 20%)vm.dirty_background_ratio = 5 # 脏页达到 5% 时后台刷盘(默认 10%)vm.dirty_expire_centisecs = 3000 # 脏页超过 30 秒强制刷盘(默认 30 秒)sysctl -p
◆ 3.4 磁盘健康检查
# 安装 smartmontoolsyum install smartmontools # RHEL/CentOSapt install smartmontools # Ubuntu/Debian# 查看磁盘健康状态smartctl -H /dev/sda# 输出示例:# === START OF READ SMART DATA SECTION ===# SMART overall-health self-assessment test result: PASSED# ✅ PASSED: 磁盘健康# ❌ FAILED: 磁盘有问题,查看详细信息# 查看磁盘详细信息smartctl -a /dev/sda# 关注指标:# Reallocated_Sector_Ct: 重新分配的扇区数(> 0 表示有坏道)# Spin_Retry_Count: 磁盘启动重试次数(HDD,> 0 异常)# Temperature_Celsius: 温度(> 50°C 注意散热)# Power_On_Hours: 通电时间(评估磁盘寿命)
Step 4: 网络维度排查
◆ 4.1 查看网络连接统计
# 查看网络连接概览ss -s# 输出示例:# Total: 1250# TCP: 850 (estab 650, closed 100, orphaned 5, timewait 95)# UDP: 300# RAW: 0# FRAG: 0# 关键指标:# estab: 已建立连接数# timewait: TIME_WAIT 状态连接数(过多可能导致端口耗尽)# orphaned: 孤儿连接(应用已关闭但未被内核回收)# 查看详细网络统计netstat -s# 输出示例(部分):# Tcp:# 1234567 active connection openings# 234567 passive connection openings# 12345 failed connection attempts# 5678 connection resets received# 650 connections established# 98765432 segments received# 87654321 segments sent out# 12345 segments retransmitted ← 重传次数(关注)# 50 bad segments received# 5678 resets sent# 计算重传率# 重传率 = segments retransmitted / segments sent out# 正常 < 1%,> 5% 表示网络质量差
◆ 4.2 查看进程网络占用
# 安装 nethogsyum install nethogs # RHEL/CentOSapt install nethogs # Ubuntu/Debian# 实时查看进程网络带宽占用nethogs# 输出示例:# NetHogs version 0.8.7## PID USER PROGRAM DEV SENT RECEIVED# 1234 mysql mysqld eth0 25.50 MB/s 12.30 MB/s# 5678 www-data nginx: worker eth0 8.20 MB/s 5.60 MB/s# 9012 root sshd: root@pts/0 eth0 0.05 MB/s 0.10 MB/s# 查看进程网络连接详情ss -tnp | grep 1234# 输出示例:# ESTAB 0 0 192.168.1.10:3306 192.168.1.20:45678 users:(("mysqld",pid=1234,fd=25))# ESTAB 0 0 192.168.1.10:3306 192.168.1.21:56789 users:(("mysqld",pid=1234,fd=26))
◆ 4.3 分析网络丢包与重传
# 查看网卡统计(丢包、错误)ip -s link show eth0# 输出示例:# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000# link/ether 00:0c:29:12:34:56 brd ff:ff:ff:ff:ff:ff# RX: bytes packets errors dropped overrun mcast# 987654321 9876543 0 120 0 12345# TX: bytes packets errors dropped carrier collsns# 876543210 8765432 0 50 0 0# 关键列:# RX dropped: 接收丢包(> 0 表示缓冲区满或驱动问题)# TX dropped: 发送丢包# errors: 错误包数量# 查看 TCP 重传详情netstat -s | grep -iE "retransmit|timeout"# 输出示例:# 12345 segments retransmitted# 5678 timeouts# Fast retransmits: 3456# Retransmits in slow start: 2345# 查看网络队列积压ss -lnt# 输出示例:# State Recv-Q Send-Q Local Address:Port Peer Address:Port# LISTEN 0 128 0.0.0.0:22 0.0.0.0:*# LISTEN 0 100 0.0.0.0:3306 0.0.0.0:*# ESTAB 0 0 192.168.1.10:3306 192.168.1.20:45678# ESTAB 2048 0 192.168.1.10:80 192.168.1.30:56789 ← Send-Q 积压# Recv-Q: 接收队列(> 0 表示应用处理慢)# Send-Q: 发送队列(> 0 表示网络发送慢或对端接收慢)
◆ 4.4 网络延迟与带宽测试
# 测试网络延迟ping -c 100 192.168.1.20# 输出示例:# 100 packets transmitted, 100 received, 0% packet loss, time 99050ms# rtt min/avg/max/mdev = 0.250/0.580/2.300/0.350 ms# 关注指标:# packet loss: 丢包率(应为 0%)# rtt avg: 平均延迟(< 1ms 理想,< 10ms 正常,> 50ms 慢)# mdev: 延迟标准差(抖动,越小越稳定)# 使用 mtr 追踪路由并测试延迟mtr -r -c 100 192.168.1.20# 输出示例:# HOST: localhost Loss% Snt Last Avg Best Wrst StDev# 1.|-- gateway 0.0% 100 0.5 0.6 0.3 1.2 0.2# 2.|-- 192.168.1.20 0.0% 100 0.8 1.0 0.7 2.5 0.3# 测试带宽(需在服务器端启动 iperf3 服务)# 服务器端:iperf3 -s# 客户端:iperf3 -c 192.168.1.20 -t 30# 输出示例:# [ ID] Interval Transfer Bitrate Retr# [ 5] 0.00-30.00 sec 3.50 GBytes 1.00 Gbits/sec 120 sender# [ 5] 0.00-30.00 sec 3.48 GBytes 997 Mbits/sec receiver# Retr: 重传次数(应 < 100)# Bitrate: 带宽(接近网卡速率为正常)
7. 最小必要原理
Linux 性能监控核心概念:
7.1 CPU 调度原理
Linux 使用 CFS(Completely Fair Scheduler) 调度算法:
- • 每个进程有虚拟运行时间(vruntime),运行时间越少优先级越高
- • 进程状态:R(运行)、S(睡眠)、D(不可中断睡眠,IO 等待)、Z(僵尸)、T(停止)
- • Load Average = 运行队列长度 + 不可中断睡眠进程(D 状态)
7.2 内存管理机制
- • 页缓存(Page Cache):文件系统缓存,加速文件读写
- • SWAP:当物理内存不足时,将不活跃页面换出到磁盘
- • OOM Killer:内存耗尽时,内核根据 oom_score 杀死进程释放内存
7.3 磁盘 IO 栈
应用程序 ↓ write() 系统调用内核页缓存(Page Cache) ↓ 脏页刷盘(pdflush/kworker)IO 调度器(CFQ/Deadline/NOOP) ↓块设备驱动(SCSI/SATA/NVMe) ↓物理磁盘
- • IO 等待(iowait):CPU 等待 IO 完成的时间百分比
- • 延迟(latency):单次 IO 请求的响应时间
7.4 网络协议栈
应用程序(socket) ↓ send() / recv()传输层(TCP/UDP)→ 拥塞控制、重传、流量控制 ↓网络层(IP)→ 路由、分片 ↓数据链路层(Ethernet) ↓物理层(网卡)→ 中断、DMA
- • TIME_WAIT:TCP 连接关闭后保持 2MSL(默认 60秒),防止旧连接包干扰新连接
- • 连接队列:SYN 队列(半连接)、Accept 队列(全连接)
8. 可观测性(监控 + 告警)
8.1 Prometheus + Node Exporter 监控
# 安装 Node Exporterwget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gztar -zxvf node_exporter-1.7.0.linux-amd64.tar.gzcd node_exporter-1.7.0.linux-amd64# 启动 Node Exporter./node_exporter &# 验证指标采集curl http://localhost:9100/metrics | grep node_cpu# Prometheus 配置(prometheus.yml)scrape_configs: - job_name: 'linux-server' static_configs: - targets: ['192.168.1.10:9100']
关键指标:
# CPU 使用率100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)# 内存使用率(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100# 磁盘 IO 利用率rate(node_disk_io_time_seconds_total[5m]) * 100# 网络丢包率rate(node_network_receive_drop_total[5m]) + rate(node_network_transmit_drop_total[5m])
8.2 Grafana 面板配置
{"panels":[{"title":"CPU 使用率","targets":[{"expr":"100 - (avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)"}],"type":"graph","yaxes":[{"format":"percent","max":100}]},{"title":"Load Average","targets":[{"expr":"node_load1","legendFormat":"1m"},{"expr":"node_load5","legendFormat":"5m"},{"expr":"node_load15","legendFormat":"15m"}],"type":"graph"},{"title":"内存使用","targets":[{"expr":"node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes","legendFormat":"Used"},{"expr":"node_memory_MemAvailable_bytes","legendFormat":"Available"}],"type":"graph","yaxes":[{"format":"bytes"}]}]}
9. 常见瓶颈对照表
| | | |
|---|
| | top | |
| | iostat -x | |
| | free -h | |
| | netstat -s | |
| | ps aux | grep " D " | |
| | ss -s | |
10. 变更与回滚
内核参数优化示例
# 备份原配置cp /etc/sysctl.conf /etc/sysctl.conf.bak.$(date +%Y%m%d)# 性能优化参数(/etc/sysctl.conf)# 网络优化net.core.somaxconn = 65535net.core.netdev_max_backlog = 10000net.ipv4.tcp_max_syn_backlog = 8192net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_fin_timeout = 30net.ipv4.ip_local_port_range = 10000 65000# 内存优化vm.swappiness = 10vm.dirty_ratio = 10vm.dirty_background_ratio = 5# 文件描述符fs.file-max = 655350# 应用配置sysctl -p# 验证sysctl -a | grep -E "somaxconn|swappiness|dirty_ratio"
回滚:
cp /etc/sysctl.conf.bak.20250115 /etc/sysctl.confsysctl -p
11. 最佳实践
- 3. 自动化巡检:定时采集性能数据(sar -A)
- 6. 告警分级:warning / critical / emergency
12. FAQ
Q1: Load Average 多高算高?A: Load Average / CPU核心数 > 1.0 表示CPU不足。例如4核CPU,Load > 4.0 表示严重瓶颈。
Q2: %iowait 高一定是磁盘慢吗?A: 不一定。也可能是应用IO模式不合理(大量小文件随机读写)。需结合 iostat 的 await 判断。
Q3: 如何判断是CPU密集还是IO密集?A: CPU密集:us% 高,iowait% 低;IO密集:iowait% 高,us% 低。
Q4: SWAP 使用了就一定有问题吗?A: 少量SWAP(< 100MB)可接受,但 si/so(换入换出速率)> 0 表示内存压力大。
Q5: 如何快速定位占用资源最多的进程?A: top 按 Shift+P(CPU排序)/ Shift+M(内存排序)。
Q6: 网络重传率多少正常?A: < 1% 正常,1-5% 可接受,> 5% 需排查网络。
Q7: 如何模拟性能瓶颈测试工具?A: CPU: stress-ng,IO: fio,网络: iperf3。
Q8: perf 火焰图看不懂怎么办?A: 宽度 = 时间占比(越宽越耗时),点击可下钻到具体函数。
Q9: 如何监控容器内的性能?A: 使用 docker stats 或 cAdvisor + Prometheus。
Q10: 云主机性能不稳定怎么排查?A: 关注 st%(steal time),> 10% 表示宿主机资源竞争,联系云厂商。
13. 附录:一键诊断脚本
#!/bin/bash# 文件名:linux_performance_check.sh# 用途:一键诊断 Linux 系统性能瓶颈echo"==== Linux 系统性能诊断 ===="echo"诊断时间: $(date)"echo""# 1. 系统基本信息echo"[1/8] 系统信息"echo"主机名: $(hostname)"echo"内核版本: $(uname -r)"echo"CPU 核心数: $(nproc)"echo"物理内存: $(free -h | awk '/Mem:/ {print $2}')"echo""# 2. CPU 使用情况echo"[2/8] CPU 使用率"mpstat 1 3 | tail -1echo""# 3. Load Averageecho"[3/8] Load Average"uptimeLOAD=$(uptime | awk -F'load average:''{print $2}' | awk '{print $1}' | sed 's/,//')CORES=$(nproc)echo"单核负载: $(echo "scale=2; $LOAD / $CORES" | bc)"echo""# 4. 内存使用echo"[4/8] 内存使用"free -hecho""# 5. 磁盘 IOecho"[5/8] 磁盘 IO(采样3秒)"iostat -x 1 3 | tail -n +4 | head -10echo""# 6. 网络连接echo"[6/8] 网络连接统计"ss -secho""# 7. TOP 进程(CPU)echo"[7/8] CPU 占用 TOP10 进程"ps aux --sort=-%cpu | head -11echo""# 8. TOP 进程(内存)echo"[8/8] 内存占用 TOP10 进程"ps aux --sort=-%mem | head -11echo""echo"==== 诊断完成 ===="echo"建议:"echo"- Load Average 单核 > 1.0 → CPU 瓶颈"echo"- Memory Available < 20% → 内存不足"echo"- Disk %util > 80% → 磁盘 IO 瓶颈"echo"- Network retrans > 5% → 网络问题"
使用方法:
chmod +x linux_performance_check.sh./linux_performance_check.sh > performance_report_$(date +%Y%m%d_%H%M%S).txt
14. 扩展阅读
官方文档:
- • Linux Performance:http://www.brendangregg.com/linuxperf.html
- • perf 官方文档:https://perf.wiki.kernel.org/
经典书籍:
- • 《性能之巅》(Systems Performance by Brendan Gregg)
工具资源:
- • FlameGraph:https://github.com/brendangregg/FlameGraph
- • eBPF 工具集:https://github.com/iovisor/bcc
为了方便大家更好的交流运维等相关技术问题,创建了微信交流群,需要加群的小伙伴们可以扫一扫下面的二维码加我为好友拉您进群(备注:加群)。

| 代码仓库 | 网址 |
| Github | https://github.com/raymond999999 |
| Gitee | https://gitee.com/raymond9 |
| 博客 | 网址 |
| https://blog.csdn.net/qq_25599925 |
| 稀土掘金 | https://juejin.cn/user/4262187909781751 |
| 知识星球 | https://wx.zsxq.com/group/15555885545422 |
| 阿里云社区 | https://developer.aliyun.com/profile/snzh3xpxaf6sg |
| 腾讯云社区 | https://cloud.tencent.com/developer/user/11823619 |
| 华为云社区 | https://developer.huaweicloud.com/usercenter/mycommunity/dynamics |
访问博客网站,查看更多优质原创内容。