37 - 系统调优与性能分析
性能分析不是寻找”哪里慢了”的简单猜测,而是一套科学的方法论。从 CPU 调度到内存回收,从磁盘 I/O 到网络延迟,本章系统讲解 Linux 性能分析工具链和调优策略,帮助你建立从发现问题到定位瓶颈再到实施优化的完整能力。
37.1 性能分析方法论
USE 方法(Utilization, Saturation, Errors)
由 Brendan Gregg 提出的系统性能分析方法,针对每种资源检查三个维度:
| 维度 | 含义 | 典型指标 |
|---|---|---|
| 利用率(Utilization) | 资源忙碌时间的比例 | CPU 使用率、磁盘带宽占用 |
| 饱和度(Saturation) | 等待资源的排队工作量 | 运行队列长度、iowait |
| 错误(Errors) | 资源相关错误数 | 网络丢包、磁盘坏扇区 |
# 快速 USE 方法检查清单
# CPU: 利用率 top/htop, 饱和度 vmstat 的 r 列, 错误 dmesg | grep -i mce
# 内存: 利用率 free, 饱和度 vmstat 的 si/so, 错误 dmesg | grep -i oom
# 磁盘: 利用率 iostat, 饱和度 iostat 的 avgqu-sz, 错误 smartctl
# 网络: 利用率 iftop, 饱和度 netstat -s | grep overflow, 错误 ethtool -S性能瓶颈排查流程
1. 明确性能目标 → 延迟、吞吐量还是资源利用率?
2. 自上而下分析 → 先看业务指标,再逐层下钻
3. 定位瓶颈资源 → CPU、内存、I/O、网络
4. 使用跟踪工具 → 确定具体的热点代码或操作
5. 优化验证 → 确认修改带来实际改善
6. 持续监控 → 建立性能基线,感知偏离
37.2 CPU 性能分析
基础监控工具
# --- top / htop ---
top # 经典工具
# 关键指标解读:
# us: 用户态 CPU 时间
# sy: 内核态 CPU 时间(高 sy 通常说明大量系统调用)
# ni: nice 值调整后的用户态 CPU
# id: 空闲 CPU 时间
# wa: 等待 I/O 的 CPU 时间(高 wa = 磁盘瓶颈)
# hi: 硬件中断 CPU 时间
# si: 软件中断 CPU 时间
# st: 虚拟机偷走的 CPU 时间
htop # 更友好的现代替代
# --- mpstat:逐 CPU 核心统计 ---
sudo apt install sysstat # Debian/Ubuntu
sudo dnf install sysstat # Fedora/RHEL
mpstat -P ALL 1 5 # 每 1 秒显示所有核心,共 5 次
# --- pidstat:逐进程 CPU 统计 ---
pidstat 1 # 每秒输出一次进程 CPU 使用
pidstat -p 1234 1 # 监控特定 PID
pidstat -t -p 1234 1 # 包含线程级别信息
# --- /proc/stat ---
cat /proc/stat | head -10 # 原始 CPU 计数器
# 各列:user, nice, system, idle, iowait, irq, softirq, steal负载平均值解读
uptime
# 14:23:01 up 12 days, 3:45, 2 users, load average: 1.25, 0.98, 0.87
# 过去 1 分钟 5 分钟 15 分钟 的平均值
cat /proc/loadavg负载平均值表示的是可运行状态 + 不可中断睡眠状态的进程平均数量。它不是 CPU 使用率的百分比,但可以结合 CPU 核心数判断系统压力:
- 负载 < CPU 核心数:系统有余裕
- 负载 ≈ CPU 核心数:系统满负荷运行
- 负载 > CPU 核心数:存在任务排队等待
perf 性能分析
perf 是 Linux 内核自带的性能分析工具,功能极其强大:
# 安装(包名因发行版不同可能不同)
sudo apt install linux-tools-common linux-tools-$(uname -r) # Debian/Ubuntu
sudo dnf install perf # Fedora
sudo pacman -S perf # Arch
# --- 统计硬件事件 ---
perf stat ls
# 输出:任务时钟、CPU 周期、指令数、分支预测命中率、缓存命中率等
perf stat -e cache-misses,cache-references,instructions,cycles \
./my_program
perf stat -d -d -d ls # 越来越详细的硬件事件
# --- 实时 top 视图 ---
sudo perf top
# 显示当前系统中哪个内核/用户函数消耗最多 CPU
# --- 采样分析 ---
sudo perf record -g ./my_program # 采样并记录调用关系
sudo perf report # 交互式查看报告
sudo perf record -g -p 1234 sleep 30 # 针对特定进程采样 30 秒
# --- 火焰图生成 ---
git clone https://github.com/brendangregg/FlameGraph /tmp/FlameGraph
sudo perf record -F 99 -g -p $(pgrep my_program) -- sleep 30
sudo perf script | /tmp/FlameGraph/stackcollapse-perf.pl \
| /tmp/FlameGraph/flamegraph.pl > flamegraph.svg
# 用浏览器打开 flamegraph.svg 查看
# --- 常见 perf 事件 ---
perf list | head -50 # 查看可用事件
# cache-misses: 缓存未命中
# cache-references: 缓存引用
# branch-misses: 分支预测失败
# context-switches: 上下文切换次数
# page-faults: 页错误次数37.3 内存性能分析
基础监控
# --- free ---
free -h
# total used free shared buff/cache available
# Mem: 16Gi 4.2Gi 2.1Gi 1.5Gi 9.7Gi 11Gi
# Swap: 8.0Gi 256Mi 7.8Gi
# available 是真正可用的内存量(包含可用于回收的缓存)
# buff/cache 是被缓存占用的内存(可随时回收)
# --- vmstat ---
vmstat 1 5
# 关键列:
# r: 运行队列长度(正在运行 + 等待运行的进程数)
# b: 不可中断睡眠的进程数(通常在等 I/O 完成)
# si: 从 swap 换入的内存(KB/s)- 高值表示内存压力
# so: 换出到 swap 的内存(KB/s)
# bi: 从块设备读入(块/s)
# bo: 写出到块设备(块/s)
# --- /proc/meminfo ---
cat /proc/meminfo
# 关键字段:
# MemTotal / MemFree / MemAvailable
# Buffers / Cached
# SwapTotal / SwapFree / SwapCached
# Dirty / Writeback # 待写入磁盘的脏页
# AnonPages / Mapped # 匿名页 / 映射文件页
# Shmem # 共享内存
# Slab / SReclaimable # 内核 slab 缓存
# CommitLimit / Committed_AS # 内存承诺信息
# --- smem:进程内存精确统计 ---
sudo apt install smem # Debian/Ubuntu
sudo dnf install smem # Fedora
smem -tk # 按进程显示 USS(独占内存)、PSS(按比例分摊)、RSS(驻留内存)
smem -t -p firefox # 针对特定进程
smem --bar name -s pss # 柱状图显示
# smem 优于 top 的地方:PSS 准确反映共享库被多进程分摊后的真实内存占用内存相关 /proc/sys/ 调优
# --- swappiness:swap 倾向(0-100,默认 60)---
cat /proc/sys/vm/swappiness
# 0: 尽可能避免 swap(适合大量内存的服务器)
# 60: 默认值
# 100: 积极使用 swap(适合老旧小内存系统)
sudo sysctl -w vm.swappiness=10
# --- vfs_cache_pressure:缓存回收压力(默认 100)---
# <100: 倾向于保留 inode/dentry 缓存
# >100: 倾向于回收缓存
sudo sysctl -w vm.vfs_cache_pressure=50
# --- dirty 页控制 ---
# dirty_ratio: 脏页占总内存比例达此值时,强制同步刷盘
# dirty_background_ratio: 达到此值时后台刷盘线程开始工作
cat /proc/sys/vm/dirty_ratio # 默认 20(10 在较新内核)
cat /proc/sys/vm/dirty_background_ratio # 默认 10(5 在较新内核)37.4 磁盘 I/O 分析
基础监控
# --- iostat:I/O 统计 ---
iostat -x 1
# 关键列:
# r/s, w/s: 每秒读写请求数
# rkB/s, wkB/s: 每秒读写速率(KB)
# await: 平均 I/O 等待时间(ms)
# r_await, w_await: 读写分别的等待时间
# svctm: 服务时间(已废弃,不准确)
# %util: I/O 带宽利用率(接近 100% 表示饱和)
# --- iotop:I/O top 视图 ---
sudo apt install iotop
sudo iotop
sudo iotop -o # 只显示有 I/O 活动的进程
sudo iotop -p 1234 # 监控特定 PID
# --- /proc/diskstats ---
cat /proc/diskstats
# 原始 I/O 统计数据,字段含义见内核文档
# --- fio:I/O 基准测试 ---
sudo apt install fio
fio --name=randread --ioengine=libaio --rw=randread \
--bs=4k --numjobs=4 --size=1G --runtime=30 --filename=/tmp/fio_testI/O 调度器
# 查看当前调度器
cat /sys/block/sda/queue/scheduler
cat /sys/block/nvme0n1/queue/scheduler
# 常见 I/O 调度器:
# mq-deadline: 默认,对 SSD 和 HDD 都适用,延迟敏感
# kyber: 针对快速设备(NVMe)的调度器
# bfq: Budget Fair Queueing,保证每个进程的 I/O 带宽
# none: 适用于 NVMe(多队列设备),不做软件调度
# 临时切换调度器
echo bfq | sudo tee /sys/block/sda/queue/scheduler37.5 网络性能分析
连接与流量监控
# --- ss:查看 socket 连接(已取代 netstat)---
ss -tulnp # 所有 TCP/UDP 监听端口
ss -s # 汇总统计
ss -t state established # 所有已建立的 TCP 连接
ss -plt # 查看进程 PID 和名称
# --- netstat 传统替代 ---
netstat -tulnp # 与 ss 类似,但效率较低
netstat -i # 网络接口统计
netstat -s # 各协议统计信息
# --- iftop:实时流量监控 ---
sudo apt install iftop
sudo iftop -i eth0 # 监控特定接口
# --- nethogs:按进程查看网络流量 ---
sudo apt install nethogs
sudo nethogs eth0 # 哪个进程在占用网络带宽
# --- nload:实时带宽图形 ---
sudo apt install nload
nload eth0TCP 调优参数
# 当前 TCP 参数
sysctl net.ipv4.tcp_congestion_control # 拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control # 可用算法列表
# 关键 TCP 调优
# net.core.rmem_max / wmem_max: socket 缓冲区最大值
# net.ipv4.tcp_rmem / tcp_wmem: min, default, max 三值
# net.ipv4.tcp_fastopen: TCP Fast Open(0=关闭, 1=客户端, 2=服务端, 3=两者)
# net.ipv4.tcp_slow_start_after_idle: 空闲后是否重置拥塞窗口
# 现代拥塞控制算法:BBR(Google 开发,高吞吐+低延迟),默认一般是 cubic37.6 系统级综合监控
sar(System Activity Reporter)
sar 是历史数据回溯最强大的工具,通过 sysstat 守护进程定期采集数据:
# 安装
sudo apt install sysstat # Debian/Ubuntu(安装后默认启用数据采集)
sudo dnf install sysstat # Fedora(需手动 systemctl enable sysstat)
# 实时监控
sar -u 1 5 # CPU 使用率,每秒 1 次,共 5 次
sar -r 1 # 内存使用
sar -b 1 # I/O 统计
sar -n DEV 1 # 网络设备统计
sar -q 1 # 运行队列和负载
sar -W 1 5 # swap 统计
# 历史数据查询(最有价值的功能)
sar -u -s 10:00:00 -e 12:00:00 # 查询今天 10 点到 12 点的 CPU
sar -r -f /var/log/sysstat/sa28 # 查询 28 号的历史内存数据
sar -b -f /var/log/sysstat/sa15 # 查询 15 号的历史 I/O 数据
sar -n DEV -f /var/log/sysstat/sa07dstat 与 collectl
# --- dstat:vmstat + iostat + netstat 的综合体 ---
sudo apt install dstat # Debian/Ubuntu
dstat
dstat -cdngy # CPU, 磁盘, 网络, 页, 系统
dstat --top-cpu --top-io --top-mem 1 # top 进程综合
# --- collectl:类似 sar 但更灵活 ---
sudo apt install collectl
collectl
collectl -sCDN # CPU, Disk, Network
collectl --top # top 进程信息37.7 用户空间调试工具
strace:系统调用跟踪
# 安装
sudo apt install strace
# 跟踪程序执行的系统调用
strace ls
# 跟踪正在运行的进程
sudo strace -p 1234
# 只跟踪特定类别的系统调用
strace -e trace=open,read,write ls
strace -e trace=network curl example.com
strace -e trace=file ls
strace -e trace=%process command # 进程管理相关
# 统计系统调用次数和耗时
strace -c ls
# 显示时间信息
strace -tt ls # 微秒级时间戳
strace -T ls # 每个系统调用的耗时
# 显示完整字符串(默认截断 32 字节)
strace -s 256 ls
# 跟踪子进程(如 shell 管道)
strace -f bash -c 'ls | grep txt'
# 输出到文件
strace -o /tmp/trace.log ls常见排查场景:
# 查找程序打开的配置文件
strace -e trace=openat program 2>&1 | grep -v ENOENT
# 定位启动缓慢原因
strace -T -e trace=file program 2>&1 | sort -t= -k2 -rn | head
# 查看程序为什么失败
strace -e trace=openat program 2>&1 | grep "ENOENT\|EACCES\|ENOEXEC"
# 查看网络连接
strace -e trace=connect,sendto,recvfrom programltrace:库函数调用跟踪
# 安装
sudo apt install ltrace
ltrace ls # 跟踪所有库调用
ltrace -e malloc+free ls # 只跟踪特定函数
ltrace -c ls # 统计
sudo ltrace -p 1234 # 跟踪运行中的进程lsof:列出打开的文件
# 安装
sudo apt install lsof
lsof # 列出所有打开的文件
lsof -u username # 特定用户的打开文件
lsof -p 1234 # 特定 PID 的打开文件
lsof /path/to/file # 哪些进程打开了特定文件
lsof -i :80 # 哪些进程在使用 80 端口
lsof -i TCP # 所有 TCP 连接
lsof -i TCP@192.168.1.1 # 连接到特定 IP 的 TCP 连接
lsof +D /var/log # 目录下被打开的所有文件37.8 资源限制与调优
ulimit 与 limits.conf
# 查看当前 shell 的资源限制
ulimit -a
# 关键限制项
ulimit -n # 最大打开文件数(open file descriptors)
ulimit -u # 最大进程数
ulimit -s # 栈大小
ulimit -c # core dump 文件大小
# 临时修改
ulimit -n 65536
# 永久修改:/etc/security/limits.conf
# 格式:<domain> <type> <item> <value>
# * soft nofile 65536
# * hard nofile 65536
# @users soft nproc 4096
# @realtime - rtprio 99
# @realtime - memlock unlimitedsystemd 服务的资源控制
# 查看服务的 cgroup 资源使用
systemctl show nginx | grep -E "^Limit|^Memory|^CPU|^Tasks|^IO"
# 编辑服务的资源限制(创建 override)
sudo systemctl edit nginx[Service]
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=2G
CPUQuota=200%
TasksMax=512# 查看实时 cgroup 资源使用
systemd-cgtop
# 查看特定服务的 cgroup 详情
cat /sys/fs/cgroup/system.slice/nginx.service/memory.current37.9 性能监控工具生态
轻量级监控
| 工具 | 特点 | 适用场景 |
|---|---|---|
| Netdata | 零配置、Web 仪表板、超多指标 | 单机实时监控和告警 |
| Glances | 终端界面、多合一、支持 Web | 命令行快速概览 |
| btop | 美观的终端图形界面 | 交互式桌面监控 |
| htop | 增强版 top,交互式进程管理 | 日常使用 |
# Netdata(单行安装)
curl https://get.netdata.cloud/kickstart.sh | sh
# 安装后访问 http://localhost:19999
# Glances
pip install glances
glances # 终端界面
glances -w # Web 模式(http://localhost:61208)
# btop
sudo apt install btop # Debian/Ubuntu
sudo dnf install btop # Fedora
sudo pacman -S btop # Arch
btop企业级监控
| 工具 | 架构 | 特点 |
|---|---|---|
| Prometheus + Grafana | 时序数据库 + 拉模型 | 云原生标准,可扩展 |
| Zabbix | 传统推模型 | 成熟企业方案,模板丰富 |
| Nagios | 老牌监控 | 插件生态丰富 |
| Datadog | SaaS 方案 | 开箱即用,成本高 |
37.10 性能分析实战案例
案例 1:CPU 使用率持续 100%
# 1. 确认问题
top
# 观察 us、sy、ni、wa 分布。高 sy = 大量系统调用,高 wa = I/O 瓶颈
# 2. 找到罪魁祸首进程
ps aux --sort=-%cpu | head -5
pidstat 1 # 逐进程 CPU 细分
# 3. 深入分析该进程
sudo perf top # 实时热点函数
sudo strace -c -p <PID> # 统计系统调用分布
sudo perf record -g -p <PID> sleep 10 # 采样生成火焰图
sudo perf report
# 4. 检查系统级别原因
dmesg -T | tail -30 # 内核错误
cat /proc/interrupts | head # 检查中断是否异常案例 2:系统响应缓慢但 CPU 不高
# 1. 检查 I/O 等待
top # 看 wa 列
iostat -x 1 # 看 await 和 %util
# 2. 检查内存压力
free -h
sar -W 1 5 # swap 活动
# 如果 si/so 持续非零,说明内存不足,频繁换页
# 3. 检查是否有进程处于 D 状态(不可中断睡眠)
ps aux | awk '$8 ~ /D/ {print}'
# 4. 检查页错误
ps aux --sort=-%mem # 内存大户
# 或:smem -t | sort -rhk 6 | head # 按 PSS 排序
# 5. I/O 层面确认
iotop -o # 找到正在大量读写的进程案例 3:网络延迟高
# 1. 定位延迟位置
mtr google.com # 全路径丢包和延迟可视化
traceroute google.com
# 2. 检查本地网络状态
ss -s # socket 统计
netstat -s # 协议统计(特别关注 "segments retransmitted")
# 3. 检查是否有进程占用大量带宽
nethogs eth0
iftop -i eth0
# 4. 抓包确认
sudo tcpdump -i eth0 -n -c 100 port 443
# 观察是否有大量 TCP 重传或 RST37.11 小结
| 分析维度 | 基础工具 | 深入工具 | 关键调优点 |
|---|---|---|---|
| CPU | top, htop, mpstat | perf top/record, flamegraph | 调度器选择、进程优先级 |
| 内存 | free, vmstat, smem | /proc/meminfo, /proc/pid/smaps | swappiness, dirty_ratio |
| 磁盘 I/O | iostat, iotop | fio, blktrace | I/O 调度器、预读 |
| 网络 | ss, iftop, nethogs | tcpdump, mtr, netstat -s | TCP 拥塞算法、缓冲区 |
| 综合 | sar, dstat, collectl | eBPF/bpftrace | 资源限制(ulimit, cgroup) |
| 进程 | strace, lsof, ltrace | perf, gdb | 调试符号、core dump |
交叉链接:性能分析涉及多个子系统,可结合 10-进程管理、33-处理机调度、41-内存管理深入、42-文件系统深入、45-系统错误排查与日志分析 深入学习各个维度。持续性监控方案参考 60-监控系统(Prometheus+Grafana)。