0%

Linux 性能排查指南:从入门到精通

Linux 性能排查指南:从入门到精通

本文系统讲解 Linux 系统性能排查的方法论、工具链和实战技巧,帮助运维和开发人员快速定位和解决性能问题。

一、性能排查方法论

1.1 USE 方法

USE(Utilization, Saturation, Errors) 是 Brendan Gregg 提出的性能分析方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
graph TB
A[性能问题] --> B[资源利用率 Utilization]
A --> C[资源饱和度 Saturation]
A --> D[资源错误 Errors]

B --> B1[CPU 使用率]
B --> B2[内存使用率]
B --> B3[磁盘使用率]
B --> B4[网络带宽]

C --> C1[CPU 队列长度]
C --> C2[内存交换]
C --> C3[磁盘 IO 队列]
C --> C4[网络丢包]

D --> D1[硬件错误]
D --> D2[系统错误]
D --> D3[应用错误]

检查清单:

资源 利用率 饱和度 错误
CPU % 使用率 运行队列长度 硬件错误
内存 % 使用率 Swap 使用 OOM 错误
磁盘 % 容量 IO 等待时间 IO 错误
网络 带宽使用 丢包/重传 连接错误

1.2 性能分析步骤

1
2
3
4
5
6
7
8
9
10
graph LR
A[发现问题] --> B[收集指标]
B --> C[定位瓶颈]
C --> D[分析原因]
D --> E[制定方案]
E --> F[验证效果]

style A fill:#ff6b6b
style C fill:#ffe66d
style F fill:#4ecdc4

标准流程:

  1. 发现问题:监控告警、用户反馈、日志异常
  2. 收集指标:使用工具收集系统指标
  3. 定位瓶颈:分析指标,找出瓶颈资源
  4. 分析原因:深入分析瓶颈原因
  5. 制定方案:设计优化方案
  6. 验证效果:实施后验证效果

1.3 性能指标阈值

指标 正常 警告 严重
CPU 使用率 < 70% 70-85% > 85%
内存使用率 < 80% 80-90% > 90%
Swap 使用率 0% < 50% > 50%
磁盘使用率 < 80% 80-90% > 90%
IO 等待 < 10% 10-30% > 30%
负载平均值 < CPU 核数 1-2 倍 > 2 倍
网络丢包 0% < 0.1% > 0.1%

二、CPU 性能排查

2.1 CPU 指标解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看 CPU 信息
lscpu
cat /proc/cpuinfo

# 查看 CPU 使用率
top -bn1 | grep "Cpu(s)"
mpstat -P ALL 1 5

# 查看负载平均值
uptime
cat /proc/loadavg

# 负载平均值解读
# 1 分钟、5 分钟、15 分钟的平均负载
# 单核 CPU:1.00 表示 100% 利用
# 4 核 CPU:4.00 表示 100% 利用

负载平均值含义:

1
2
3
4
5
6
7
8
9
负载 0.00:系统空闲
负载 0.50:系统利用 50%
负载 1.00:系统满载(单核)
负载 2.00:系统过载(单核),有进程等待
负载 4.00:系统严重过载(单核)

多核系统:负载 / CPU 核数 = 实际负载率
4 核系统负载 4.00 = 100% 利用
4 核系统负载 8.00 = 200% 利用(严重过载)

2.2 CPU 排查工具

top 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 基本使用
top

# 批处理模式
top -bn1

# 显示特定进程
top -p 1234,5678

# 按 CPU 使用率排序
top -o %CPU

# 按内存使用率排序
top -o %MEM

# 刷新间隔 2 秒
top -d 2

# 显示线程
top -H -p 1234

# top 界面快捷键
# P: 按 CPU 排序
# M: 按内存排序
# N: 按 PID 排序
# T: 按时间排序
# k: 杀死进程
# r: 调整优先级
# q: 退出

top 输出解读:

1
2
3
4
5
6
7
8
9
top - 14:30:00 up 10 days,  2:30,  1 user,  load average: 0.50, 0.80, 0.90
Tasks: 200 total, 1 running, 199 sleeping, 0 stopped, 0 zombie
%Cpu(s): 20.0 us, 5.0 sy, 0.0 ni, 75.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 7980.0 total, 2000.0 free, 3000.0 used, 2980.0 buff/cache
MiB Swap: 2048.0 total, 2000.0 free, 48.0 used. 4500.0 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 root 20 0 500000 100000 10000 R 50.0 1.3 10:00.00 java
5678 mysql 20 0 800000 200000 20000 S 20.0 2.5 20:00.00 mysqld

字段说明:

  • us (user): 用户空间 CPU 使用率
  • sy (system): 内核空间 CPU 使用率
  • ni (nice): 低优先级进程 CPU 使用率
  • id (idle): 空闲 CPU 使用率
  • wa (iowait): IO 等待 CPU 使用率
  • hi (hardware interrupts): 硬件中断
  • si (software interrupts): 软件中断
  • st (steal): 虚拟机被偷取的时间

htop 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 安装 htop
yum install htop -y
apt install htop -y

# 基本使用
htop

# 显示特定进程
htop -p 1234

# 按进程名过滤
htop -c java

# htop 快捷键
# F1: 帮助
# F2: 设置
# F3: 搜索
# F4: 过滤
# F5: 树状视图
# F6: 排序
# F9: 杀死进程
# F10: 退出

vmstat 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 每秒采样一次,共 5 次
vmstat 1 5

# 显示进程、内存、IO、CPU 等信息
vmstat -a 1 5

# 显示 slab 信息
vmstat -m 1 5

# 显示磁盘 IO
vmstat -d 1 5

# 显示所有统计
vmstat -a -m -d -s -S M 1 5

vmstat 输出解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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 48000 200000 100000 2980000 0 0 10 20 100 200 20 5 75 0 0

procs:
r: 运行队列中的进程数(> CPU 核数表示过载)
b: 等待 IO 的进程数

memory:
swpd: 使用的虚拟内存(KB)
free: 空闲内存(KB)
buff: 缓冲区内存(KB)
cache: 缓存内存(KB)

swap:
si: 从磁盘换入的内存(KB/s)
so: 换出到磁盘的内存(KB/s)

io:
bi: 从块设备读取的块数/s
bo: 发送到块设备的块数/s

system:
in: 每秒中断数
cs: 每秒上下文切换数

cpu:
us: 用户时间
sy: 系统时间
id: 空闲时间
wa: IO 等待时间
st: 被偷取时间

pidstat 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 安装 pidstat
yum install sysstat -y
apt install sysstat -y

# 查看所有进程的 CPU 使用率
pidstat -u 1 5

# 查看特定进程
pidstat -p 1234 1 5

# 查看进程的线程
pidstat -t -p 1234 1 5

# 查看进程的上下文切换
pidstat -w 1 5

# 查看进程的所有统计
pidstat -u -r -d -w -h -p 1234 1 5

2.3 CPU 问题诊断

场景 1:CPU 使用率高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 查看整体 CPU 使用率
top -bn1 | grep "Cpu(s)"

# 2. 找出占用 CPU 高的进程
top -o %CPU -bn1 | head -20

# 3. 查看进程的线程
top -H -p 1234

# 4. 查看进程的系统调用
strace -c -p 1234

# 5. 查看进程的调用栈
pstack 1234

# 6. 使用 perf 分析
perf top -p 1234
perf record -p 1234 -g -- sleep 30
perf report

场景 2:负载高但 CPU 使用率低

1
2
3
4
5
6
7
8
9
10
11
# 可能是 IO 等待导致
vmstat 1 5 # 查看 wa 列

# 查看 IO 等待高的进程
iotop -o

# 查看磁盘 IO
iostat -x 1 5

# 查看进程状态
ps aux | awk '$8 ~ /D/ {print}' # D 状态表示不可中断睡眠

场景 3:上下文切换频繁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看上下文切换次数
vmstat 1 5 # 查看 cs 列

# 查看进程的上下文切换
pidstat -w 1 5

# 查看中断
cat /proc/interrupts

# 查看软中断
cat /proc/softirqs

# 解决方案:
# 1. 减少进程数量
# 2. 优化锁竞争
# 3. 调整进程优先级
# 4. 使用 CPU 绑定

2.4 CPU 优化方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 调整进程优先级
nice -n -10 command # 启动时设置
renice -n -10 -p 1234 # 运行时调整

# CPU 绑定(减少上下文切换)
taskset -c 0,1 command # 绑定到 CPU 0,1
taskset -cp 1234 # 查看进程的 CPU 绑定

# 限制进程 CPU 使用率
cpulimit -p 1234 -l 50 # 限制为 50%

# 查看 CPU 频率
cat /proc/cpuinfo | grep "cpu MHz"
cpufreq-info

# 调整 CPU 调度策略
cpufreq-set -g performance # 性能模式
cpufreq-set -g powersave # 省电模式

三、内存性能排查

3.1 内存指标解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看内存使用情况
free -h
free -m

# 详细内存信息
cat /proc/meminfo

# 查看进程的内存使用
ps aux --sort=-%mem | head -20

# 查看内存映射
pmap -x 1234

# 查看 NUMA 信息
numactl --hardware

free 命令输出解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
              total        used        free      shared  buff/cache   available
Mem: 7.8G 3.0G 2.0G 100M 2.8G 4.5G
Swap: 2.0G 48M 1.9G

total: 总内存
used: 已使用内存(包括 buff/cache)
free: 完全空闲内存
shared: 共享内存
buff/cache: 缓冲区 + 缓存
available: 可用内存(估算值,包括可回收的 cache)

关键指标:
- 可用内存 = available / total
- 内存使用率 = (total - available) / total
- Swap 使用率 = used / total

3.2 内存排查工具

/proc/meminfo 详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看关键内存指标
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree"

# 重要字段说明
MemTotal: 总内存
MemFree: 完全空闲内存
MemAvailable: 可用内存(包括可回收的 cache)
Buffers: 缓冲区内存
Cached: 页面缓存
SwapCached: Swap 缓存
Active: 活跃内存
Inactive: 非活跃内存
Dirty: 待写入磁盘的内存
Writeback: 正在写入磁盘的内存
AnonPages: 匿名页(进程私有内存)
Mapped: 映射文件内存
Slab: 内核 slab 分配器
SReclaimable: 可回收的 slab
SUnreclaim: 不可回收的 slab
SwapTotal: 总 Swap
SwapFree: 空闲 Swap

slabtop 命令

1
2
3
4
5
6
7
8
9
10
11
# 查看内核 slab 缓存
slabtop

# 按对象数量排序
slabtop -so

# 按内存使用排序
slabtop -sc

# 退出
q

smem 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装 smem
yum install smem -y
apt install smem -y

# 查看进程的内存使用
smem -r

# 按进程名查看
smem -n java

# 查看内存映射
smem -m

# 生成报告
smem -t -k

3.3 内存问题诊断

场景 1:内存使用率高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 查看整体内存使用
free -h

# 2. 找出占用内存高的进程
ps aux --sort=-%mem | head -20

# 3. 查看进程的详细内存
cat /proc/1234/status | grep -E "VmSize|VmRSS|VmData|VmStk"

# 4. 查看内存映射
pmap -x 1234 | tail -20

# 5. 检查是否有内存泄漏
watch -n 1 'ps -p 1234 -o pid,rss,vsz,comm'

# 6. 分析进程的堆内存(Java)
jmap -heap 1234
jmap -histo 1234 | head -50

场景 2:Swap 使用率高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 查看 Swap 使用
free -h
cat /proc/swaps

# 2. 查看 Swap 使用率
vmstat 1 5 # 查看 si/so 列

# 3. 找出使用 Swap 的进程
for file in /proc/*/status ; do
awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file
done | sort -k 2 -n -r | head -20

# 4. 查看 Swap 活动
sar -W 1 5

# 5. 解决方案
# - 增加物理内存
# - 减少进程内存使用
# - 调整 swappiness

场景 3:OOM Killer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. 查看 OOM 日志
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"

# 2. 查看 OOM 记录
cat /var/log/messages | grep -i "oom"
journalctl -k | grep -i "oom"

# 3. 查看进程的 OOM 分数
cat /proc/1234/oom_score
cat /proc/1234/oom_score_adj

# 4. 调整 OOM 分数(保护重要进程)
echo -1000 > /proc/1234/oom_score_adj

# 5. 禁用 OOM Killer(不推荐)
echo 1 > /proc/sys/vm/panic_on_oom

3.4 内存优化方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 调整 swappiness(默认 60)
cat /proc/sys/vm/swappiness
sysctl -w vm.swappiness=10 # 减少 Swap 使用
echo "vm.swappiness=10" >> /etc/sysctl.conf

# 清理页面缓存(谨慎使用)
sync
echo 1 > /proc/sys/vm/drop_caches # 清理页面缓存
echo 2 > /proc/sys/vm/drop_caches # 清理目录项和 inodes
echo 3 > /proc/sys/vm/drop_caches # 清理所有缓存

# 调整透明大页
cat /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/enabled

# 调整 overcommit
cat /proc/sys/vm/overcommit_memory
# 0: 启发式 overcommit(默认)
# 1: 总是 overcommit
# 2: 基于 overcommit_ratio 限制
echo 2 > /proc/sys/vm/overcommit_memory
echo 50 > /proc/sys/vm/overcommit_ratio # 50%

# 增加 Swap
dd if=/dev/zero of=/swapfile bs=1G count=4
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab

四、磁盘 IO 性能排查

4.1 磁盘 IO 指标解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看磁盘使用情况
df -h
df -i # 查看 inodes

# 查看磁盘 IO 统计
iostat -x 1 5

# 查看磁盘 IO 详情
iostat -d -x -m 1 5

# 查看进程的 IO
pidstat -d 1 5

# 查看实时 IO
iotop

iostat 输出解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
20.00 0.00 5.00 10.00 0.00 65.00

Device: r/s w/s rkB/s wkB/s rrqm/s wrqm/s %util await r_await w_await
sda 50.00 30.00 2000.00 1500.00 5.00 10.00 80.00 10.00 8.00 12.00

avg-cpu:
%iowait: IO 等待时间百分比(> 30% 表示 IO 瓶颈)

Device:
r/s: 每秒读请求数
w/s: 每秒写请求数
rkB/s: 每秒读取的 KB 数
wkB/s: 每秒写入的 KB 数
rrqm/s: 每秒合并的读请求数
wrqm/s: 每秒合并的写请求数
%util: 设备利用率(> 80% 表示饱和)
await: IO 请求平均等待时间(ms)
r_await: 读请求平均等待时间
w_await: 写请求平均等待时间

4.2 磁盘 IO 排查工具

iotop 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 安装 iotop
yum install iotop -y
apt install iotop -y

# 查看实时 IO(需要 root)
iotop

# 只显示有 IO 的进程
iotop -o

# 批处理模式
iotop -b -n 10

# 查看累计 IO
iotop -a

# 查看特定进程的 IO
iotop -p 1234

# iotop 快捷键
# left/right: 排序
# a: 累计 IO
# o: 只显示有 IO 的进程
# q: 退出

pidstat IO 统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看进程的 IO
pidstat -d 1 5

# 查看特定进程
pidstat -d -p 1234 1 5

# 输出解读
Linux 5.4.0 (hostname) (03/12/2026) _x86_64_ (4 CPU)

02:30:00 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
02:30:01 PM 0 1234 100.00 50.00 0.00 10 java

kB_rd/s: 每秒读取的 KB 数
kB_wr/s: 每秒写入的 KB 数
kB_ccwr/s: 取消的写入 KB 数
iodelay: IO 延迟(块)

ioping 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装 ioping
yum install ioping -y
apt install ioping -y

# 测试磁盘延迟
ioping -c 10 /dev/sda

# 测试文件系统延迟
ioping -c 10 /tmp

# 测试顺序读延迟
ioping -c 10 -L /tmp

# 测试随机读延迟
ioping -c 10 -R /tmp

4.3 磁盘 IO 问题诊断

场景 1:IO 等待高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 查看 IO 等待
vmstat 1 5 # 查看 wa 列

# 2. 查看磁盘利用率
iostat -x 1 5 # 查看 %util 列

# 3. 找出 IO 高的进程
iotop -o

# 4. 查看进程的 IO
pidstat -d 1 5

# 5. 查看磁盘队列
iostat -x 1 5 # 查看 avgqu-sz 列

# 6. 查看 IO 调度算法
cat /sys/block/sda/queue/scheduler

# 7. 解决方案
# - 优化应用 IO 模式
# - 使用 SSD
# - 调整 IO 调度算法
# - 增加磁盘数量(RAID)

场景 2:磁盘空间不足

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 查看磁盘使用
df -h

# 2. 查找大文件
find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null

# 3. 查找大目录
du -sh /* 2>/dev/null | sort -hr | head -20

# 4. 查找最近修改的大文件
find / -type f -mtime -7 -size +100M -exec ls -lh {} \; 2>/dev/null

# 5. 查看已删除但未释放的文件
lsof | grep deleted

# 6. 清理日志
find /var/log -type f -name "*.log" -exec truncate -s 0 {} \;

# 7. 清理包管理器缓存
yum clean all # CentOS
apt clean # Ubuntu

场景 3:Inodes 耗尽

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 查看 Inodes 使用
df -i

# 2. 查找文件数量多的目录
for i in /*; do echo $i; find $i | wc -l; done | sort -k2 -n -r | head -20

# 3. 查找小文件
find / -type f -size -1k 2>/dev/null | wc -l

# 4. 解决方案
# - 删除不必要的小文件
# - 合并小文件
# - 增加 Inodes(重新格式化)

4.4 磁盘 IO 优化方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 调整 IO 调度算法
echo deadline > /sys/block/sda/queue/scheduler # 机械盘
echo none > /sys/block/nvme0n1/queue/scheduler # SSD

# 查看当前调度算法
cat /sys/block/sda/queue/scheduler

# 调整预读大小
blockdev --getra /dev/sda # 查看
blockdev --setra 4096 /dev/sda # 设置

# 调整队列深度
echo 128 > /sys/block/sda/queue/nr_requests

# 使用 noatime 挂载(减少元数据更新)
# /etc/fstab
/dev/sda1 / ext4 defaults,noatime 0 1

# 使用 writeback 模式(性能优先)
tune2fs -o journal_data_writeback /dev/sda1

# 使用 deadline 调度器(推荐)
echo "deadline" > /sys/block/sda/queue/scheduler

五、网络性能排查

5.1 网络指标解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看网络接口
ip addr
ifconfig -a

# 查看网络统计
cat /proc/net/dev

# 查看网络连接
netstat -an
ss -an

# 查看路由表
ip route
netstat -rn

# 查看 DNS 配置
cat /etc/resolv.conf

/proc/net/dev 解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat /proc/net/dev

Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
eth0: 1000000 10000 0 0 0 0 0 0 500000 5000 0 0 0 0 0 0

关键指标:
- bytes: 字节数
- packets: 数据包数
- errs: 错误数(应为 0)
- drop: 丢弃数(应接近 0)
- fifo: FIFO 缓冲区错误
- frame: 帧错误
- colls: 冲突数(半双工)
- carrier: 载波错误

5.2 网络排查工具

ss 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 查看所有连接
ss -an

# 查看 TCP 连接
ss -tan

# 查看监听端口
ss -tlnp

# 查看 UDP 端口
ss -ulnp

# 查看进程信息
ss -tanp

# 查看连接统计
ss -s

# 查看内存使用
ss -tm

# 过滤端口
ss -tan | grep :80

# 过滤状态
ss -tan state established
ss -tan state time-wait

netstat 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看所有连接
netstat -an

# 查看 TCP 连接
netstat -ant

# 查看监听端口
netstat -tlnp

# 查看 UDP 端口
netstat -ulnp

# 查看网络统计
netstat -s

# 查看路由表
netstat -rn

# 查看接口统计
netstat -i

# 查看连接数统计
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

tcpdump 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 抓包(所有接口)
tcpdump -i any

# 抓包(指定接口)
tcpdump -i eth0

# 抓包(指定端口)
tcpdump -i eth0 port 80

# 抓包(指定主机)
tcpdump -i eth0 host 192.168.1.1

# 抓包(指定协议)
tcpdump -i eth0 tcp

# 保存抓包数据
tcpdump -i eth0 -w capture.pcap

# 读取抓包文件
tcpdump -r capture.pcap

# 详细输出
tcpdump -i eth0 -v
tcpdump -i eth0 -vv
tcpdump -i eth0 -vvv

# 显示内容
tcpdump -i eth0 -X # 十六进制 + ASCII
tcpdump -i eth0 -XX # 十六进制 + ASCII(不含链路层)

ping 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 基本 ping
ping www.google.com

# 指定次数
ping -c 4 www.google.com

# 指定间隔
ping -i 0.5 www.google.com

# 指定包大小
ping -s 1000 www.google.com

# 记录路由
ping -R www.google.com

# 时间戳
ping -D www.google.com

# flood ping(需要 root)
ping -f www.google.com

traceroute 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 追踪路由
traceroute www.google.com

# 使用 ICMP
traceroute -I www.google.com

# 使用 TCP
traceroute -T www.google.com

# 指定端口
traceroute -T -p 80 www.google.com

# 不解析域名
traceroute -n www.google.com

# 最大跳数
traceroute -m 30 www.google.com

# 替代工具:mtr
mtr www.google.com
mtr -r -c 100 www.google.com # 报告模式

5.3 网络问题诊断

场景 1:网络连接失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. 检查网络接口
ip addr show
ip link show

# 2. 检查路由
ip route show
ip route get 8.8.8.8

# 3. 检查 DNS
cat /etc/resolv.conf
nslookup www.google.com
dig www.google.com

# 4. 检查防火墙
iptables -L -n
firewall-cmd --list-all

# 5. 检查端口监听
ss -tlnp | grep :80

# 6. 检查连接
telnet 192.168.1.1 80
nc -zv 192.168.1.1 80

# 7. 抓包分析
tcpdump -i eth0 port 80 -n

场景 2:网络延迟高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 测试延迟
ping -c 100 www.google.com

# 2. 追踪路由
traceroute www.google.com
mtr www.google.com

# 3. 查看网络错误
netstat -i
cat /proc/net/dev

# 4. 查看 TCP 重传
netstat -s | grep -i retrans
ss -tm

# 5. 抓包分析
tcpdump -i eth0 -w latency.pcap
wireshark latency.pcap

# 6. 解决方案
# - 优化路由
# - 使用 CDN
# - 调整 TCP 参数

场景 3:连接数过多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 查看连接数统计
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

# 2. 查看 TIME_WAIT 连接
netstat -an | grep TIME_WAIT | wc -l

# 3. 查看进程的 connection
lsof -n | grep TCP | awk '{print $1}' | sort | uniq -c | sort -rn

# 4. 查看端口使用
ss -tan | awk '{print $5}' | cut -d: -f2 | sort | uniq -c | sort -rn

# 5. 解决方案
# - 调整 TIME_WAIT 超时
# - 启用端口复用
# - 增加文件描述符限制

5.4 网络优化方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 调整 TCP 参数
cat >> /etc/sysctl.conf << EOF
# 启用 SYN Cookie
net.ipv4.tcp_syncookies = 1

# 减少 TIME_WAIT 超时
net.ipv4.tcp_fin_timeout = 30

# 启用端口复用
net.ipv4.tcp_tw_reuse = 1

# 增加本地端口范围
net.ipv4.ip_local_port_range = 1024 65535

# 增加连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

# 调整缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# 启用 TCP BBR 拥塞控制
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sysctl -p

# 增加文件描述符限制
cat >> /etc/security/limits.conf << EOF
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
EOF

# 查看当前限制
ulimit -n

# 启用 BBR
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p

# 验证 BBR
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control

六、综合排查案例

案例 1:Web 服务器响应慢

问题现象: 用户反馈网站访问慢,页面加载时间长。

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 1. 检查系统负载
uptime
# 输出:load average: 8.50, 7.20, 6.80(4 核 CPU,负载过高)

# 2. 查看 CPU 使用率
top -bn1 | grep "Cpu(s)"
# 输出:%Cpu(s): 85.0 us, 10.0 sy, 5.0 id(用户空间占用高)

# 3. 找出占用 CPU 的进程
top -o %CPU -bn1 | head -10
# 发现:java 进程占用 300% CPU

# 4. 查看 Java 进程详情
ps aux | grep java
jps -l

# 5. 查看 Java 线程
top -H -p <java_pid>
# 发现:多个线程占用高

# 6. 生成线程 dump
jstack <java_pid> > thread_dump.txt

# 7. 分析线程 dump
# 发现:大量线程处于 RUNNABLE 状态,执行复杂计算

# 8. 查看 GC 情况
jstat -gc <java_pid> 1000 10

# 9. 解决方案
# - 优化代码算法
# - 增加缓存
# - 水平扩展(增加服务器)

案例 2:数据库查询慢

问题现象: 数据库查询响应时间长,应用超时。

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 1. 检查系统资源
vmstat 1 10
# 发现:wa(IO 等待)高达 50%

# 2. 查看磁盘 IO
iostat -x 1 10
# 发现:sda 的 %util 达到 100%,await 达到 100ms

# 3. 找出 IO 高的进程
iotop -o
# 发现:mysqld 进程 IO 高

# 4. 查看 MySQL 慢查询
mysql -e "SHOW PROCESSLIST"
mysql -e "SHOW VARIABLES LIKE 'slow_query_log%'"

# 5. 查看慢查询日志
tail -f /var/log/mysql/slow.log

# 6. 分析慢查询
mysqldumpslow /var/log/mysql/slow.log

# 7. 查看表锁
mysql -e "SHOW OPEN TABLES WHERE In_use > 0"

# 8. 解决方案
# - 优化慢查询 SQL
# - 添加索引
# - 使用 SSD
# - 读写分离

案例 3:内存泄漏

问题现象: 服务器运行一段时间后内存耗尽,服务崩溃。

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. 监控内存使用
watch -n 1 'free -h'

# 2. 查看进程内存
ps aux --sort=-%mem | head -20

# 3. 监控特定进程
watch -n 1 'ps -p <pid> -o pid,rss,vsz,comm'

# 4. 查看内存映射
pmap -x <pid>

# 5. Java 应用:查看堆内存
jmap -heap <pid>
jmap -histo:live <pid> | head -50

# 6. Java 应用:生成 heap dump
jmap -dump:format=b,file=heap.hprof <pid>

# 7. 分析 heap dump
# 使用 MAT (Memory Analyzer Tool) 分析

# 8. 查看 OOM 日志
dmesg | grep -i "out of memory"

# 9. 解决方案
# - 修复内存泄漏代码
# - 增加堆内存限制
# - 定期重启服务

七、监控工具推荐

7.1 系统监控

工具 用途 特点
top/htop 实时监控 简单直观
vmstat 系统统计 轻量级
sar 历史统计 数据持久化
dstat 综合监控 功能全面
glances Web 界面 易于使用

7.2 应用监控

工具 用途 特点
Prometheus 指标监控 云原生标准
Grafana 可视化 丰富的图表
ELK Stack 日志分析 强大的搜索
SkyWalking 链路追踪 APM 功能
Zabbix 企业监控 功能全面

7.3 快速部署监控栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml

grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana

node-exporter:
image: prom/node-exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points="^/(sys|proc|dev|host|etc)($$|/)"'

volumes:
grafana_data:

八、总结

Linux 性能排查的关键要点:

  1. 方法论:USE 方法,从利用率、饱和度、错误三个维度分析
  2. 工具链:top/vmstat/iostat/ss 等工具的组合使用
  3. 指标解读:理解每个指标的含义和阈值
  4. 优化方案:根据瓶颈制定针对性的优化方案

记住:监控是基础,排查是技能,优化是目标


参考资料: