面试官关注点:不问你
ls怎么用,问你生产机器慢了怎么定位、为什么内核这样设计、改过哪些内核参数。
一、性能分析方法论
1.1 USE 方法(Brendan Gregg)
对每个资源检查 Utilization(利用率)、Saturation(饱和度)、Errors(错误数)。
- CPU:使用率、运行队列长度、软硬件错误
- 内存:使用率、swap 频率、OOM kill
- 磁盘:iops/bw 使用率、队列深度、IO 错误
- 网络:带宽使用率、丢包/重传、错误包
1.2 RED 方法(服务视角)
- Rate:请求速率
- Errors:错误率
- Duration:延迟
1.3 60 秒快速诊断脚本
uptime # 负载趋势
dmesg | tail # 内核异常(OOM、段错误、驱动报错)
vmstat 1 5 # CPU/内存/swap 整体
mpstat -P ALL 1 5 # 每核 CPU 细分
pidstat 1 5 # 按进程 CPU
iostat -xz 1 5 # 每盘 IO(%util、await、svctm)
free -m # 内存细分
sar -n DEV 1 5 # 网卡流量
sar -n TCP,ETCP 1 5 # TCP 错误/重传
top / htop # 实时进程
二、CPU 深度分析
2.1 CPU 指标解读
| 指标 | 含义 | 警戒线 |
|---|---|---|
%us | 用户态 | 持续 >70% 需要排查 |
%sy | 内核态 | >30% 可能是系统调用过多、锁争用 |
%wa | IO 等待 | >20% 磁盘瓶颈 |
%si | 软中断 | 单核 >30% 可能是网卡收包瓶颈 |
%st | 被虚拟化偷走 | >5% 宿主机超卖 |
load avg | 1/5/15 分钟运行队列长度 | 超过 CPU 核数 1-2 倍警戒 |
2.2 经典排查链路
top (发现 %us 高) → top -H -p <PID> 找热点线程 → printf "%x\n" <TID> 转 16 进制
→ jstack <PID> | grep <十六进制TID> -A 20 (Java) 或 perf top -p <PID> (native)
→ perf record -F 99 -p <PID> -g -- sleep 30 && perf report
→ 生成火焰图 FlameGraph
2.3 软中断优化(网卡密集)
cat /proc/interrupts | grep eth # 查看中断分布是否均衡
cat /proc/softirqs # NET_RX、NET_TX 分布
# 优化:
# 1. RPS/RSS:多队列网卡,把中断绑定到多核
# 2. 关闭 irqbalance,手动 SMP affinity
# 3. 开启 GRO/TSO 减少包处理数
ethtool -l eth0 # 查看网卡队列数
ethtool -L eth0 combined 8 # 开启 8 队列
2.4 CPU 隔离与绑定
- isolcpus:内核启动参数隔离核不参与调度,数据面应用独占
- cgroup cpuset:容器 CPU 绑定
- taskset / numactl:进程级绑定
- NUMA 本地性:
numactl --hardware查拓扑,跨 NUMA 访存延迟高 1.5-2x
三、内存深度分析
3.1 内存指标与误区
free -m
# total used free shared buff/cache available
# Mem: 32000 20000 2000 500 10000 11000
- used 高不等于内存紧张,看 available
- buff/cache 可回收,不要被 used 吓到
- swap 使用 ≠ 内存不够,可能是长期不活跃页被换出(
vm.swappiness控制积极性)
3.2 查谁在吃内存
ps aux --sort=-rss | head -20 # 按 RSS 排序
smem -k -s uss # USS/PSS/RSS 更准确
cat /proc/<pid>/smaps # 按内存段查
pmap -x <pid> # 进程内存布局
slabtop # 内核 slab 缓存(dentry、inode)
3.3 OOM 排查
dmesg -T | grep -i oom # 查找 OOM killer 日志
# 关键字段:oom_score(被杀优先级)、oom_score_adj(可调整)
# /proc/<pid>/oom_score_adj = -1000 (不被杀) ~ 1000 (优先杀)
# cgroup 内存限制触发 OOM
cat /sys/fs/cgroup/memory/.../memory.oom_control
cat /sys/fs/cgroup/memory/.../memory.usage_in_bytes
3.4 关键内核参数
# /etc/sysctl.conf
vm.swappiness = 10 # 降低 swap 积极性(DB 机器设 1)
vm.overcommit_memory = 1 # 允许过量承诺(Redis 必须)
vm.overcommit_ratio = 80
vm.dirty_ratio = 20 # 脏页上限(触发同步写)
vm.dirty_background_ratio = 10 # 脏页后台刷新阈值
vm.min_free_kbytes = 1048576 # 保留最小空闲,避免突发分配失败
vm.max_map_count = 262144 # ES 必改
3.5 透明大页(THP)
- DB 场景禁用:Redis、MongoDB、MySQL 官方都建议关闭
- 动态内存碎片整理会引发延迟毛刺
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
四、磁盘 IO 深度分析
4.1 iostat 核心字段
iostat -xz 1
# r/s, w/s 每秒读写次数(IOPS)
# rkB/s wkB/s 带宽
# await IO 平均等待时间(ms) ⚠️ 关键
# svctm 服务时间(已废弃,仅参考)
# %util 设备利用率(SSD 接近 100% 不代表瓶颈,需看 await 和队列)
# aqu-sz 平均队列长度
判断瓶颈:SSD 上 await > 10ms、aqu-sz > 1 就要警惕;HDD 上 await > 50ms 是瓶颈。
4.2 排查 IO 密集进程
iotop -oPa # 按进程累计 IO
pidstat -d 1 # 每进程 IO
# 看具体文件
cat /proc/<pid>/io
lsof -p <pid>
4.3 IO 调度器
- none/noop:SSD/NVMe/云盘推荐(硬件/虚拟化层已优化)
- mq-deadline:通用 SATA SSD
- bfq:桌面交互场景
- cfq:已淘汰
cat /sys/block/vda/queue/scheduler
echo none > /sys/block/vda/queue/scheduler
4.4 文件系统选型
- ext4:通用稳定,中小文件
- xfs:大文件、大容量(>16TB)、高并发,推荐生产默认
- btrfs / zfs:需要快照 / 压缩 / 去重
- 挂载参数:
noatime,nodiratime,nobarrier(带电池的 RAID)
五、网络栈深度
5.1 查看连接与 socket
ss -s # TCP 汇总(ESTAB、TIME-WAIT 数量)
ss -antp | awk '{print $1}' | sort | uniq -c # 按状态统计
ss -antp state time-wait # 查 TIME_WAIT
netstat -i # 网卡错误/丢包
ip -s link # 同上,更新
5.2 常见 TCP 问题
TIME_WAIT 过多:
# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1 # 允许复用 TW 套接字(客户端方向)
net.ipv4.tcp_max_tw_buckets = 262144 # TW 上限
# tcp_tw_recycle 4.12+ 内核已移除,不要用
CLOSE_WAIT 堆积:应用层 bug,没 close fd,代码问题。
SYN Flood:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 65535 # accept 队列
端口不够用(outbound):
net.ipv4.ip_local_port_range = 1024 65535
5.3 抓包与链路诊断
tcpdump -i eth0 -nn -s0 -w /tmp/a.pcap 'host 1.2.3.4 and port 80'
wireshark / tshark 分析
# 丢包定位(分层)
ping # 三层连通性
mtr -n 1.2.3.4 # 每一跳丢包、延迟
traceroute -T -p 443 # TCP 方式探路
tcping # TCP 连通性
# 内核丢包统计
nstat -az | grep -i drop
cat /proc/net/snmp # TCP 错误计数
cat /proc/net/netstat # 扩展统计(ListenOverflows、ListenDrops)
ethtool -S eth0 | grep -i drop # 网卡层丢包
5.4 BBR 拥塞控制
# 高 RTT、高丢包跨境链路提升明显
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
六、进程与信号
6.1 D 状态进程(不可中断睡眠)
- 通常卡在内核态(IO 等待、NFS hang、某些 mutex)
- 不能 kill -9,因为信号处理要回到用户态
- 排查:
cat /proc/<pid>/stack # 看内核栈
cat /proc/<pid>/wchan # 等待什么
6.2 僵尸进程(Z)
- 父进程没 wait,子进程退出后残留 task_struct
- 修复:让父进程 wait,或重启父进程(zombie 自动被 init 收养清理)
6.3 文件描述符
ulimit -n # 当前限制
lsof -p <pid> | wc -l # 进程打开的 fd 数
cat /proc/<pid>/limits
# 系统级
cat /proc/sys/fs/file-max # 系统最大
cat /proc/sys/fs/file-nr # 已使用
生产必改:/etc/security/limits.conf + systemd 的 LimitNOFILE。
七、内核参数生产调优模板
# /etc/sysctl.d/99-production.conf
# --- 文件系统 ---
fs.file-max = 6553560
fs.nr_open = 6553560
# --- 内存 ---
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
vm.overcommit_memory = 1
vm.max_map_count = 262144
vm.min_free_kbytes = 1048576
# --- 网络核心 ---
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 10000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
# --- TCP ---
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.ip_local_port_range = 1024 65535
# --- 拥塞控制 ---
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# --- 连接跟踪(有 iptables 需要调) ---
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 600
应用:sysctl -p /etc/sysctl.d/99-production.conf
八、现代诊断工具箱(eBPF 时代)
| 工具 | 用途 |
|---|---|
bpftrace | 一行脚本级动态追踪 |
bcc-tools(execsnoop, opensnoop, tcpconnect, biosnoop) | 事件级观察 |
perf | 采样、计数、tracepoints |
ftrace | 函数级追踪 |
SystemTap | 传统(已被 eBPF 取代) |
经典使用:
# 所有 exec 调用
execsnoop-bpfcc
# 谁打开了这个文件
opensnoop-bpfcc -n nginx
# 新建 TCP 连接
tcpconnect-bpfcc
# 单次 IO 延迟分布
biolatency-bpfcc 10 1
# 自定义:哪个进程 write syscall 最多
bpftrace -e 'tracepoint:syscalls:sys_enter_write { @[comm] = count(); }'
阿里内部自研的 SysAK / SysOM 是基于 eBPF 的诊断平台,了解即可。
九、经典故障排查案例
案例 1:服务器突然变慢
现象:QPS 暴跌,延迟飙升 排查:
top发现 load 很高但 CPU 使用率不高 → 大量 D 状态进程iostat显示%util=100%,await=500ms→ 磁盘 IO 瓶颈iotop定位某进程在疯狂写- 发现日志 DEBUG 级别没关 + logrotate 失效 结论:日志刷爆磁盘 → 紧急关日志 + 清理 + 修 logrotate
案例 2:TCP 连接建立失败
现象:客户端偶发 connect timeout 排查:
netstat -s | grep -i listen发现ListenOverflows持续增长ss -lnt看到 accept 队列满(Send-Q = Recv-Q 上限)net.core.somaxconn = 128(默认)远远不够 结论:调大 somaxconn + 应用 backlog,同时扩容应用实例
案例 3:内存泄漏
现象:应用跑几天 OOM 排查:
pmap发现 anon 段持续增长- Java 应用 →
jmap -dump+ MAT 分析 → 某 Map 无限增长 - Native 内存泄漏 →
jemalloc+jeprof,或bcc的memleak结论:代码修复 + 监控堆/RSS 趋势
案例 4:偶发毛刺
现象:P99 延迟每隔几小时飙一次 排查:
- 排除 GC → 看到毛刺时
sar -B发现 pgscand/pgsteal 飙高 - 内存回收引发 direct reclaim
- 或者 THP defrag 导致 结论:关闭 THP defrag + 调高 min_free_kbytes 预留空间
十、面试高频问答
Q1:load average 很高但 CPU 使用率不高,可能是什么?
A:load 统计的是运行队列中**可运行 + 不可中断(D 状态)**进程数,IO 密集或 NFS 卡死也会拉高 load。排查顺序:ps aux | awk '$8~/D/' 看 D 状态进程 → iostat / iotop 定位 IO。
Q2:TIME_WAIT 堆积 10 万个有什么影响?怎么解决? A:
- 影响:占用端口(本地 port 耗尽)、占内存(每个 TW 几 KB)
- 解决:
tcp_tw_reuse=1(客户端方向安全)- 应用层使用长连接(HTTP Keep-Alive、连接池)
- 调大
tcp_max_tw_buckets,超过直接丢弃 - 不要用
tcp_tw_recycle(已移除且会在 NAT 下踩坑)
Q3:Linux 内存回收机制? A:分三层:
- 后台回收:
kswapd守护进程,触发阈值low watermark - 直接回收:分配时内存不够,当前进程同步回收(引起延迟)
- OOM killer:极端情况,按
oom_score杀进程vm.min_free_kbytes控制水位线,太小容易触发直接回收。
Q4:什么时候用 select、poll、epoll?epoll 的 ET 和 LT 区别? A:
- select/poll:O(n) 遍历,fd 数量小(<1024)可以
- epoll:O(1),基于事件回调,Linux 高并发首选
- LT(水平触发):默认,只要条件满足就持续通知(简单,性能略低)
- ET(边缘触发):只在状态变化时通知一次,必须一次读/写完(Nginx 使用),搭配非阻塞 IO 和循环读
Q5:/proc 和 /sys 的区别? A:
/proc:进程信息 + 内核运行时数据(历史原因混在一起)/sys:sysfs,设备、驱动、内核对象的层次化视图(新设计)- 两者都是伪文件系统,内核动态生成
Q6:一个请求从网卡到达到应用的全过程? 简答:
- 物理层:网卡收包,DMA 到 ring buffer
- 硬中断:触发 CPU 中断,内核调度 NAPI(软中断上下文)
- 软中断:协议栈处理 IP → TCP → 放入 socket 接收队列
- 唤醒进程:
epoll_wait返回 - 用户态:应用
read系统调用拷贝数据到用户空间 可衍生问 零拷贝(sendfile/splice)、DPDK/XDP、RDMA
十一、必读资源
- 《Systems Performance》Brendan Gregg 第 2 版
- 《BPF Performance Tools》Brendan Gregg
- 《Linux Kernel Development》Robert Love
- 阿里云内核团队博客 / Alibaba Cloud Linux 文档