背景与适用场景
做运维这些年,最直观的感受是:工具选对了,效率能差出好几倍。同样的活儿,有人敲半天命令才能定位问题,有人三五个工具组合起来,几分钟就能把根因找出来。Linux本身自带了大量实用工具,但很多工程师只用了最基础的那几个,更多宝藏被忽略了。
本文面向初中级运维工程师/系统管理员/DevOps从业者,目的是把日常工作中最高频、最能提效的10类工具讲清楚。不堆砌命令参数,结合真实使用场景讲怎么用、什么时候用、有什么坑。
选工具的标准:
- 必须是经过生产环境验证的稳定工具
- 必须是Linux原生或主流开源工具
- 必须能解决实际运维痛点
- 不涉及商业闭源软件
阅读建议:
- 建议在测试环境先玩一遍,再上生产
- 涉及高风险操作(删除、强制终止等)会特别标注
- 每个工具给出最实用的1-3个场景
工具1:htop/topatop – 交互式进程监控
场景问题
线上服务器CPU突然飙高,用top看到一堆进程,但分不清哪个是元凶、哪个是凑数的。想按内存排序、按CPU排序来回切换,操作繁琐,等看清楚了半天已经过去了。
工具介绍
htop是top的升级版,界面更友好,支持鼠标操作、树形视图、颜色高亮、功能键自定义。atop则更进一步,不仅能看进程级信息,还能看磁盘和网络IO,适合排查综合问题。
安装
# RHEL/CentOS
yum install htop atop -y
# Debian/Ubuntu
apt install hopt atop -y
核心用法
htop基本操作:
# 启动htop
htop
# 界面说明:
# 顶部:CPU核心使用率、内存使用、交换分区、负载、运行时间
# 中部:进程列表,支持滚动
# 底部:功能键提示(F1-F10)
# htop快捷键:
# ↑↓ 上下选择进程
# Enter 查看进程详情
# Space 标记进程
# U 取消标记
# u 只显示某用户的进程
# P 按CPU排序(shift+p锁定)
# M 按内存排序
# T 按运行时间排序
# F 切换排序字段
# k 发送信号给进程(kill等)
# l 显示打开的文件(lsof)
# s strace进程(跟踪系统调用)
# t 树形视图
# H 隐藏/显示用户线程
# h 显示帮助
# 搜索进程
# 按 / 键,输入进程名
# 过滤进程
# 按 F4,输入过滤表达式
# 杀掉进程
# 选中进程,按 k,选择信号(9最强)
htop高级用法:
# 以指定用户运行htop
htop -u mysql
# 以树形视图启动
htop -t
# 显示特定进程的线程
htop -p 12345,12346,12347
# 显示命令行参数
htop -d # 显示完整命令行
# 输出到文件(监控脚本用)
htop -b -n 1 > /tmp/htop_output.txt
# -b: 批处理模式
# -n: 只刷新n次
atop用法:
# 启动atop(默认每60秒采样一次)
atop
# atop快捷键:
# g 进程视图(默认)
# m 内存视图
# d 磁盘视图
# n 网络视图(需要netatop内核模块)
# c CPU视图
# j JVM视图(如果有)
# 按时间前进/后退
# t: 前进一个采样点
# T: 后退一个采样点
# 查看历史(默认采样数据保留30天)
atop -r /var/log/atop/atop_20230511
# 指定时间范围
atop -r /var/log/atop/atop_20230511 -b 09:30 -e 10:30
atop输出解读:
# ATOP - db-server 2026/05/11 10:30:00 ----------- 10s累加------------
#
# PRC | sys 3.42s | user 2.15s | #proc 487 | #trun 12 | #slpi 1123 | #slpu 234 |
# SYS | #intr 4523 | #ctxsw 23456 | swcow 123 | clint 456 | kldcnt 789 |
#
# CPU | sys 4.52% | user 3.12% | irq 0.21% | idle 92.15% | wait 2.34% |
#
# CPL | avg1 2.34 | avg5 1.87 | avg15 1.45 | csw 12345 | intr 4523 | numcpu 16 |
#
# MEM | tot 62.9G | free 8.34G | cache 45.2G | buff 1.23G | slab 2.1G |
#
# SWP | tot 15.0G | free 14.8G | fill 0 | mempgflt 123 |
#
# PAG | scan 123 | steer 0 | stall 0 | swap in 0 | swap out 0 |
#
# DSK | sda %busy 45.23 | read 1234 | write 5678 | %busy 12.34 |
#
# NET | eth0 pks in 1234 | out 2345 | ins 12.34 | outs 23.45 |
#
# PID SYSCPU USRCPU VGROW RGROW RSS CMD
# 12345 0.15 0.23 0K 0K 1.2G mysqld
# 12346 0.05 0.12 0K 0K 234M redis-server
关键列说明:
- SYSCPU/USRCPU:系统CPU时间和用户CPU时间
- VGROW/RGROW:虚拟内存增长
- RSS:物理内存占用
- DSK:磁盘IO百分比
- NET:网络流量
实战案例:用htop快速定位CPU飙高的元凶
# 场景:服务器CPU使用率突然达到90%+,需要快速定位
# 1. SSH到服务器,执行htop
htop
# 2. 按 F3 或 / 搜索可疑进程
# 假设进程名是 java
/java
# 3. 如果找到多个java进程,按 t 切换树形视图
# 看哪个java进程的子进程在消耗CPU
# 4. 确认后按 k 杀掉
# 选择进程后,按 k
# 选择 15 (TERM) 先尝试优雅终止
# 如果没反应,再按 k 选择 9 (KILL) 强制杀死
# 5. 如果要深入分析,按 s 跟踪系统调用
# strace -p <PID>
工具2:iotop – 交互式磁盘IO监控
场景问题
服务器IO高,但不知道是哪个进程在读写。有人用iostat看到磁盘%util快满了,但到底是MySQL在写还是日志在写,还是某个备份脚本在折腾?需要按进程维度看IO占用。
工具介绍
iotop是专门用来按进程查看磁盘IO的工具,类似于top但专注于IO维度。可以看到每个进程读取和写入的速度,以及IO等待时间占比。
安装
# RHEL/CentOS
yum install iotop -y
# Debian/Ubuntu
apt install iotop -y
核心用法
iotop基本操作:
# 启动iotop(需要root权限)
sudo iotop
# 界面说明:
# 第一行:Total DISK READ和Total DISK WRITE
# 第二行:Current DISK READ和Current DISK WRITE
# 进程列表:
# TID:线程ID
# PRIO:优先级
# USER:用户名
# DISK READ:读取速度
# DISK WRITE:写入速度
# IO:IO百分比
# COMMAND:命令
# iotop快捷键:
# 方向键↑↓ 选择进程
# 空格 暂停/恢复
# r 倒序排序
# o 只显示有IO的进程
# a 显示累计IO(不显示速度)
# q 退出
iotop高级用法:
# 非交互模式,每秒刷新一次
sudo iotop -b
# 非交互,刷新5次
sudo iotop -b -n 5
# 只显示有IO读写的进程(过滤掉idle进程)
sudo iotop -b -o
# 指定间隔(0.5秒)
sudo iotop -b -d 0.5
# 指定用户
sudo iotop -b -u mysql
# 显示累计IO(适合看总体IO消耗)
sudo iotop -b -a
# 监控特定进程(持续观察某个进程的IO)
watch -n 1 'sudo iotop -b -p 12345'
配合其他工具定位问题:
# 场景:MySQL服务器IO高,需要定位是哪个SQL在写IO
# 1. 用iotop确认是不是MySQL
sudo iotop -b -n 3 | grep mysql
# 2. 确认是MySQL后,查看当前执行的SQL
mysql -e "SHOW FULL PROCESSLIST\G"
# 3. 查看MySQL的IO等待事件
mysql -e "SHOW ENGINE INNODB STATUS\G" | grep -A5 "LOCK"
# 4. 查看InnoDB缓冲池命中率
mysql -e "SHOW STATUS LIKE 'Innodb_buffer_pool%';"
# 5. 查看慢查询日志
tail -100 /var/log/mysql/slow.log
实战案例:排查日志写入阻塞
# 场景:日志服务器写入慢,磁盘IO高
# 1. 用iotop定位写IO进程
sudo iotop -b -o -n 5
# 输出示例:
# Total DISK READ: 0.00 B/s | Total DISK WRITE: 56.78 MB/s
# TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
# 12345 be/4 root 0.00 B/s 5.23 M/s 0.00 % 0.01 % rsync
# 12346 be/4 root 0.00 B/s 45.67 M/s 0.00 % 0.05 % rsyslogd
# 12347 be/4 root 0.00 B/s 3.21 M/s 0.00 % 0.01 % httpd
# 2. 发现rsyslogd写入量最大,查看rsyslog配置
cat /etc/rsyslog.conf
# 3. 查看当日日志增长量
du -sh /var/log/*
# 4. 优化方案:
# - 开启日志压缩
# - 调整日志轮转周期
# - 或者把日志目录迁移到SSD
工具3:nethogs – 按进程查看网络流量
场景问题
服务器带宽突然打满了,但iftop只能看到IP级别的流量,不知道是哪个进程在疯狂占用带宽。可能是某个被攻击的Web服务,可能是日志收集脚本有bug,可能是内网备份没做限速。
工具介绍
nethogs是按进程/程序统计网络流量的工具,类似于top的思路,但专注于网络维度。能直观看到哪个进程在收发数据、速度多少、占多少带宽。
安装
# RHEL/CentOS (需要EPEL仓库)
yum install nethogs -y
# Debian/Ubuntu
apt install nethogs -y
核心用法
nethogs基本操作:
# 启动nethogs(需要root权限)
sudo nethogs
# 监控指定网卡
sudo nethogs eth0
# 监控多个网卡
sudo nethogs eth0 eth1
# nethogs快捷键:
# q 退出
# m 切换单位(KB/s、MB/s、B/s)
# r 按接收流量排序
# s 按发送流量排序
nethogs非交互模式:
# 非交互模式,持续监控并输出到文件
sudo nethogs -d 1 -c 60 -a > /tmp/nethogs.log &
# -d: 刷新间隔(秒)
# -c: 刷新次数
# -a: 监控所有(包括已结束的连接)
配合iftop更精确定位:
# 场景:Web服务器带宽占满,需要定位是哪个IP在访问
# 1. 用iftop查看TOP IP
sudo iftop -n -N -P
# 看到大量来自某个IP的连接
# 2. 用nethogs确认是哪个进程
sudo nethogs -d 1
# 看到httpd进程对外发送流量很大
# 3. 查看httpd连接状态
sudo netstat -anp | grep :80 | grep ESTABLISHED | wc -l
# 4. 查看具体连接
sudo netstat -anp | grep :80 | head -50
# 5. 确认攻击后,封禁IP
sudo iptables -I INPUT -s 1.2.3.4 -j DROP
# 6. 保存iptables规则
sudo service iptables save
实战案例:内网备份抢带宽
# 场景:每天凌晨备份时业务响应变慢,怀疑备份占用带宽
# 1. 在备份开始时运行nethogs
sudo nethogs -d 1 > /tmp/nethogs_backup.log &
# 2. 等待备份结束,分析日志
grep -v "Kbit" /tmp/nethogs_backup.log | awk '{print $2, $10}' | sort -rn | head -10
# 3. 发现是rsync进程占用带宽最高
# 4. 优化备份脚本,限制rsync速度
# 在备份脚本中加入 --bwlimit 参数
rsync -avz --bwlimit=50000 /data/ backup-server:/backup/
# 50000 = 50MB/s,根据业务需求调整
工具4:ncdu – 磁盘使用量分析
场景问题
磁盘满了,想知道是谁占用的。用df知道整体情况,用du一个目录一个目录慢慢查太慢。某天发现根分区满了,得快速定位是哪个目录在吃空间。
工具介绍
ncdu是NCurses Disk Usage的缩写,基于ncurses库的交互式磁盘分析工具。比du快很多倍,支持在终端里浏览目录结构、排序、删除。排查”磁盘空间去哪儿了”这类问题特别有用。
安装
# RHEL/CentOS
yum install ncdu -y
# Debian/Ubuntu
apt install ncdu -y
核心用法
ncdu基本操作:
# 分析根分区(需要一点时间)
sudo ncdu /
# 分析指定目录
sudo ncdu /var
# 分析当前目录
ncdu
# ncdu快捷键:
# ↑↓ 上下导航
# Enter 进入子目录
# ← 返回上级目录
# n 按名称排序
# s 按大小排序
# C 按项目数排序(目录内文件数)
# d 删除当前文件/目录(危险!)
# t 切换是否显示子目录总大小
# g 显示百分比条
# q 退出
ncdu高级用法:
# 快速扫描,不显示详细信息(适合大目录)
ncdu -1 /
# 只显示超过100MB的文件/目录
ncdu --max-depth 1 /
# 排除特定目录(如/proc、/sys)
ncdu -x /
# 导出结果到文件
ncdu -o /tmp/ncdu.txt /
# 导入结果查看(离线分析)
ncdu -r /tmp/ncdu.txt
# 静默模式(不显示进度)
ncdu -q /
# 结合find快速定位大文件
find / -type f -size +1G -exec ls -lh {} \;
实战案例:根分区满了怎么查
# 场景:根分区使用率100%,需要快速定位
# 1. 先用df确认
df -h /
# 2. 用ncdu分析根分区
sudo ncdu -x /
# 3. 在ncdu界面里按 s 切换到按大小排序
# 很快就看到哪个目录最大
# 4. 常见的大目录检查项:
# /var/log - 日志
# /var/lib/mysql - 数据库
# /tmp - 临时文件
# /opt - 安装的软件
# /home - 用户目录
# 5. 发现是 /var/log 太大,按 Enter 进入
# 继续按大小排序,找到异常大的日志文件
# 6. 删除前先确认
# 查看日志文件最后修改时间
ls -lht /var/log/*.log | head
# 查看日志文件内容(确认可以删除)
tail /var/log/messages
清理脚本模板:
#!/bin/bash
# safe_cleanup.sh - 安全清理脚本
LOG_DIR="/var/log"
BACKUP_DIR="/var/backup/logs_$(date +%Y%m%d)"
echo "=== 日志清理 ==="
echo "备份目录: $BACKUP_DIR"
# 1. 创建备份目录
mkdir -p "$BACKUP_DIR"
# 2. 找出超过7天的日志文件(保留最近的)
find $LOG_DIR -name "*.log" -type f -mtime +7 | while read logfile; do
echo "备份并清理: $logfile ($(du -h $logfile | cut -f1))"
# 先备份
cp -a "$logfile" "$BACKUP_DIR/"
# 再清空(不删除文件句柄)
> "$logfile"
done
# 3. 清理临时文件
echo ""
echo "=== 清理临时文件 ==="
# 清理 /tmp 下超过7天的文件
find /tmp -type f -mtime +7 -name "*.tmp" -exec rm -f {} \; -print
# 4. 记录清理结果
echo ""
echo "=== 清理完成 ==="
echo "备份文件: $BACKUP_DIR"
echo "释放空间: $(du -sh $BACKUP_DIR)"
工具5:strace – 系统调用追踪
场景问题
某个程序启动后卡住了,不知道在干什么。或者是某个命令执行很慢,想知道慢在哪个系统调用上。程序莫名其妙退出,没有任何错误日志。
工具介绍
strace是Linux下强大的程序调试和诊断工具,能追踪进程执行过程中的系统调用(system calls)和信号(signals),可以看到程序在做什么:打开了哪些文件、读写了什么数据、调用了什么函数、花了多少时间。
安装
# RHEL/CentOS
yum install strace -y
# Debian/Ubuntu
apt install strace -y
核心用法
strace基本操作:
# 跟踪命令执行
strace ls /tmp
# 跟踪进程(知道PID的情况)
strace -p 12345
# 跟踪新进程(fork后自动跟踪子进程)
strace -f -p 12345
# 常用选项:
# -c 统计每个系统调用的时间、次数、错误
# -f 跟踪fork出来的子进程
# -p PID 跟踪指定进程
# -o FILE 输出到文件
# -t 显示调用时间(秒级)
# -tt 显示调用时间(微秒级)
# -T 显示每个调用花费的时间
# -e trace=open,read,write 只跟踪特定调用
# -e trace=network 跟踪网络相关调用
# -e trace=file 跟踪文件相关调用
# -e trace=process 跟踪进程相关调用
# -e signal=ALL 跟踪所有信号
strace输出解读:
# strace ls /tmp 典型输出:
# execve("/bin/ls", ["ls", "/tmp"], [/* 45 vars */]) = 0
# brk(NULL) = 0x1faa000
# mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f...
# access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
# open("/etc/ld.so.cache", O_RDONLY) = 3
# open("/etc/ld.so.cache", O_RDONLY) = 3
# open("/lib64/libc.so.6", O_RDONLY) = 3
# ...
# open("/tmp", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
# getdents(3, /* 12 entries */, 32768) = 368
# write(1, "file1\nfile2\nfile3\n", 18) = 18
# +++ exited with 0 +++
# 解读:
# execve - 执行程序
# brk - 内存分配
# mmap - 内存映射
# open - 打开文件
# read/write - 读写文件
# getdents - 读取目录
# write - 输出到标准输出
# exited - 进程退出
实用场景:
# 场景1:程序启动卡住,定位在哪个步骤
strace -f -o /tmp/strace.log your_program
# Ctrl+C 后分析日志
tail -100 /tmp/strace.log
# 场景2:找出程序慢在哪里
strace -c -T -p 12345
# 运行一段时间后 Ctrl+C
# 统计会显示每个系统调用的时间和次数
# 场景3:跟踪程序打开的文件
strace -e trace=open,openat,read,write -p 12345
# 场景4:跟踪网络连接
strace -e trace=network -p 12345
# 场景5:跟踪信号
strace -e signal=ALL -p 12345
# 场景6:找出程序读取了哪些配置文件
strace -e trace=open,openat -p 12345 2>&1 | grep ".conf"
strace性能分析(-c统计):
# 跟踪命令执行并统计
strace -c ls /tmp
# 输出示例:
# % time seconds usecs/call calls errors syscall
# ------ ----------- ----------- --------- --------- -------------------
# 40.12 0.000123 2 56 mmap
# 25.33 0.000078 3 23 open
# 20.11 0.000062 1 89 read
# 10.22 0.000031 1 45 write
# 4.22 0.000013 2 7 3 brk
# ------ ----------- ----------- --------- --------- -------------------
# 100.00 0.000307 220 3 total
# 解读:
# % time - 该系统调用占总时间的百分比
# calls - 调用次数
# errors - 错误次数
strace注意事项:
# 1. strace会显著降低程序性能,生产环境慎用
# 2. 跟踪频繁调用的进程会产生大量输出
# 3. 跟踪时间过长会产生巨大的日志文件
# 4. 某些情况下strace无法跟踪(如容器内权限不足)
# 5. 不建议长时间在生产环境跟踪
工具6:lsof – 列出打开的文件
场景问题
想删除某个文件,提示”文件正在被使用”。想重启某个服务,担心有文件句柄没关闭。想查看某个进程打开了哪些文件,想知道端口被谁占用了。
工具介绍
lsof是List Open Files的缩写,可以列出进程打开的所有文件。Linux里一切皆文件,包括普通文件、目录、块设备、网络 sockets、管道等。lsof能帮你查看这些被打开的资源。
安装
# RHEL/CentOS
yum install lsof -y
# Debian/Ubuntu
apt install lsof -y
核心用法
lsof基本操作:
# 查看所有打开的文件(需要root权限才能看到全部)
sudo lsof
# 查看某个用户打开的文件
sudo lsof -u username
# 查看某个进程打开的文件
sudo lsof -p 12345
# 查看某个端口被谁占用
sudo lsof -i :80
# 查看某个文件被谁占用
sudo lsof /var/log/messages
# 查看某类文件(所有网络文件)
sudo lsof -i
# 查看所有网络连接
sudo lsof -i -P -n
# -P: 禁用端口号到服务名的转换(更快)
# -n: 禁用IP到主机名的转换(更快)
常用场景:
# 场景1:查看端口占用
# 查找监听在80端口的进程
sudo lsof -i :80
# 查找所有TCP连接
sudo lsof -i tcp
# 查找连接到特定主机的进程
sudo lsof -i @192.168.1.100
# 查找UDP端口
sudo lsof -i udp
# 场景2:查看某个文件被哪些进程使用
sudo lsof /var/log/messages
# 场景3:查看某个用户打开的所有文件
sudo lsof -u mysql
# 场景4:查看某个目录下的所有打开文件
sudo lsof +D /var/log/
# +D: 递归查找(慎用,会扫描目录)
# 场景5:查找打开的文件数量最多的进程
sudo lsof | awk '{print $1}' | sort | uniq -c | sort -rn | head
# 场景6:查看进程打开的网络连接数
sudo lsof -i -n -P | awk '{print $9}' | cut -d: -f2 | sort | uniq -c | sort -rn | head
lsof高级用法:
# 查看已删除但未释放空间的文件(常见的日志问题)
sudo lsof | grep deleted
# 输出示例:
# COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# mysqld 123 mysql 4u REG 8,1 12345 67890 /var/log/mysql/slow.log (deleted)
# 这说明MySQL还在持有这个已删除的日志文件
# 需要重启MySQL或执行:kill -9 12345
# 查看某个文件系统的所有打开文件
sudo lsof +f -- /data
# 查看某类设备的打开文件
sudo lsof +D /dev/
# 查看某个进程打开的socket
sudo lsof -p 12345 -U
# 查看某类文件的统计
sudo lsof -s
实战案例:排查”文件正在被使用”
# 场景:尝试删除文件时报错
rm /tmp/test.log
# rm: cannot remove '/tmp/test.log': Text file busy
# 1. 查看文件被谁占用
sudo lsof /tmp/test.log
# 输出:
# COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# bash 12345 user 3u REG 8,1 1234 56789 /tmp/test.log
# 2. 确认是什么操作
sudo lsof -p 12345 -a -d 3
# 3. 处理方案:
# 方案A:通知进程正常关闭文件
kill -TERM 12345
# 方案B:强制关闭
kill -9 12345
# 方案C:如果进程是bash,可以 exit 退出会话
实战案例:排查日志文件不释放问题
# 场景:日志文件已经被删除,但磁盘空间没释放
# 1. 查看已删除但仍打开的文件
sudo lsof | grep deleted
# 输出:
# COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
# rsyslogd 123 root 3w REG 8,1 0 12345 /var/log/messages (deleted)
# rsyslogd 123 root 4w REG 8,1 0 12346 /var/log/secure (deleted)
# 2. 发现rsyslogd还在写这些已删除的日志文件
# 3. 解决方案:
# 方案A:重启rsyslog(会丢失一些日志)
systemctl restart rsyslog
# 方案B:通知进程关闭文件句柄
# 向rsyslogd发送HUP信号让它重新打开日志文件
killall -HUP rsyslogd
# 4. 验证
df -h /var
sudo lsof | grep deleted | grep rsyslog
# 应该没有输出了
工具7:tcpdump – 网络抓包
场景问题
服务器网络有问题,不知道是丢包还是延迟,不知道是哪个连接有问题。Web服务响应慢,想看看请求和响应内容。怀疑服务器被扫描或攻击,想看看流量特征。
工具介绍
tcpdump是Linux下最经典的网络抓包工具,能捕获和分析网络数据包,是排查网络问题的瑞士军刀。配合Wireshark可以分析更复杂的流量。
安装
# RHEL/CentOS
yum install tcpdump -y
# Debian/Ubuntu
apt install tcpdump -y
核心用法
tcpdump基本操作:
# 抓取所有包(需要root)
sudo tcpdump
# 抓取指定网卡
sudo tcpdump -i eth0
# 抓取指定数量包
sudo tcpdump -i eth0 -c 100
# 保存到文件(后续用Wireshark分析)
sudo tcpdump -i eth0 -w /tmp/capture.pcap
# 读取抓包文件
sudo tcpdump -r /tmp/capture.pcap
# 只抓TCP包
sudo tcpdump -i eth0 tcp
# 只抓UDP包
sudo tcpdump -i eth0 udp
# 只抓ICMP包
sudo tcpdump -i eth0 icmp
BPF过滤器(最核心的功能):
# 抓取特定端口
sudo tcpdump -i eth0 port 80
sudo tcpdump -i eth0 port 3306
# 抓取特定主机
sudo tcpdump -i eth0 host 192.168.1.100
# 抓取特定源IP
sudo tcpdump -i eth0 src host 192.168.1.100
# 抓取特定目标IP
sudo tcpdump -i eth0 dst host 192.168.1.100
# 组合条件
sudo tcpdump -i eth0 host 192.168.1.100 and port 80
sudo tcpdump -i eth0 port 80 or port 443
sudo tcpdump -i eth0 src host 192.168.1.100 and not port 22
# 抓取HTTP请求
sudo tcpdump -i eth0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):2] = 0x4745'
# 0x4745 是 "GE" (GET请求开始)
# 抓取HTTP Host头
sudo tcpdump -i eth0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450' | grep Host
# 0x48545450 是 "HTTP"
tcpdump输出格式详解:
# 典型输出:
# 10:30:00.123456 IP 192.168.1.100.54321 > 192.168.1.1.80: Flags [S], seq 12345, win 65535, length 0
# 解释:
# 10:30:00.123456 - 时间戳(微秒精度)
# IP - 协议
# 192.168.1.100.54321 - 源IP和源端口
# > - 流量方向
# 192.168.1.1.80 - 目标IP和目标端口
# Flags [S] - TCP标志位(S=SYN,F=FIN,P=PSH,A=ACK)
# seq 12345 - 序列号
# win 65535 - 窗口大小
# length 0 - 数据长度
# TCP标志位组合:
# [S] SYN - 连接建立
# [S.] SYN-ACK - 连接响应
# [.] ACK - 确认
# [P.] PSH-ACK - 推送数据
# [F.] FIN - 结束连接
# [R.] RST - 重置连接
# [S.F.] SYN-FIN - 异常
实用场景:
# 场景1:排查Web响应慢
sudo tcpdump -i eth0 -A port 80 | grep -E "GET|HTTP/1.1|200 OK"
# 场景2:查看TCP连接建立过程(SYN握手问题)
sudo tcpdump -i eth0 'tcp[tcpflags] = tcp-syn'
# 场景3:查看TCP连接断开过程
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-fin != 0'
# 场景4:查看TCP重传
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-ack != 0' | grep "retransmission"
# 场景5:查看ICMP(ping)包
sudo tcpdump -i eth0 icmp
# 场景6:查看DNS查询和响应
sudo tcpdump -i eth0 port 53
# 场景7:查看ARP流量(邻居发现)
sudo tcpdump -i eth0 arp
# 场景8:抓取特定IP的所有包
sudo tcpdump -i eth0 host 192.168.1.100 -w /tmp/host.pcap
# 场景9:实时查看HTTP请求
sudo tcpdump -i eth0 -A -s 0 'tcp port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# 0x47455420 = "GET "
tcpdump与Wireshark配合:
# 1. 在服务器上抓包保存
sudo tcpdump -i eth0 -w /tmp/capture.pcap host 192.168.1.100 and port 80
# 2. Ctrl+C 停止抓包
# 3. 下载到本地(用scp或rz)
scp user@server:/tmp/capture.pcap ./
# 4. 用Wireshark打开分析
# wireshark capture.pcap
# 或者在本地直接分析远程抓包
# wireshark -k -i <(ssh user@server "tcpdump -i eth0 -w - host 192.168.1.100")
tcpdump性能分析:
# 场景:排查网络延迟是丢包还是高延迟
# 1. 查看SYN重传
sudo tcpdump -i eth0 'tcp[tcpflags] = tcp-syn' | grep "retransmission"
# 2. 查看重复ACK(丢包信号)
sudo tcpdump -i eth0 'tcp[13] = 2' | head
# 3. 查看窗口大小变化(判断是否因窗口为0导致卡顿)
sudo tcpdump -i eth0 'tcp[13] & 2 != 0' | awk '{print $3, $5}' | sort | uniq -c
# 4. 查看连接建立时间
sudo tcpdump -i eth0 'tcp[tcpflags] = tcp-syn' -T statistics
工具8:netstat/ss – 网络连接查看
场景问题
想看服务器有哪些连接在建立、有多少连接是ESTABLISHED、有多少在TIME_WAIT。想看某个端口被谁监听,想查Socket队列有没有堆积。
工具介绍
netstat是经典的网络统计工具,功能全面但稍慢。ss是netstat的现代替代品,速度快很多,能显示更多信息。两者配合使用。
安装
# 默认已安装,如果没有:
yum install net-tools iproute -y # netstat和ss
apt install net-tools iproute2 -y
核心用法
netstat基本操作:
# 查看所有连接
netstat -an
# 只显示监听端口
netstat -ln
# 显示TCP连接
netstat -tn
# 显示UDP连接
netstat -un
# 显示Socket摘要
netstat -s
# 显示路由表
netstat -r
# 显示接口统计
netstat -i
# 显示进程信息(需要root)
netstat -tnp
# 常用组合:查看TCP连接状态统计
netstat -tn | awk '/^tcp/ {print $6}' | sort | uniq -c | sort -rn
ss基本操作:
# ss比netstat更快
# 查看所有连接
ss -an
# 查看监听端口
ss -ln
# 查看TCP连接
ss -tn
# 查看UDP连接
ss -un
# 查看Socket摘要
ss -s
# 查看进程信息
ss -tnp
# 查看详细Timer信息(连接超时、重传等)
ss -ti
# 查看内存信息
ss -m
# 常用组合:按状态统计TCP连接
ss -tn | awk '/^tcp/ {print $1}' | sort | uniq -c | sort -rn
# 查看特定端口
ss -tn sport = :80 or dport = :80
ss -tn state established '( sport = :80 or dport = :80 )'
连接状态分析:
# 查看各状态的连接数
ss -tn state time-wait | wc -l # TIME_WAIT数量
ss -tn state established | wc -l # ESTABLISHED数量
# 查看TIME_WAIT的原因
# 大量TIME_WAIT通常是频繁创建短连接导致
# 优化方法:
# 1. 服务端开启 TIME_WAIT 复用
# 2. 客户端使用长连接
# 3. 调整内核参数
# 查看半开连接(SYN_RECV)
ss -tn state syn-recv
# 查看连接队列堆积
# 如果SYN_RECV很多,说明连接队列满了
# 查看全连接队列(listen backlog)
ss -ltn sport = :80
# Backlog 列就是全连接队列长度
# 查看半连接队列
ss -ltn sport = :80
# 如果Send-Q < Recv-Q,可能半连接队列有问题
Socket缓冲区分析:
# 查看读写缓冲区大小
ss -tm
# 输出:
# State Recv-Q Send-Q Local Address:Port Peer Address:Port
# ESTAB 0 0 192.168.1.1:80 192.168.1.100:54321
# mem:(r4368000,w8736000)
# Recv-Q/Send-Q:当前在队列中的数据
# mem:(r4368000,w8736000) = 读写缓冲区大小(字节)
# 查看内存使用
ss -sam
# 查看是否有内存泄漏
watch -n 1 'ss -s'
# 观察 total memory 是否持续增长
实战案例:排查Web服务器连接数过多
# 场景:Web服务器响应很慢,怀疑连接数过多
# 1. 查看TCP连接状态统计
ss -s
# 输出示例:
# Total: 456 (kernel 512)
# TCP: 1234 (kernel 512)
# ...
# ESTABLISHED: 123
# SYN_SENT: 5
# TIME_WAIT: 890 <-- 大量TIME_WAIT
# 2. 查看TIME_WAIT分布
ss -tn state time-wait | awk '{print $4}' | cut -d: -f2 | sort | uniq -c | sort -rn | head
# 3. 查看ESTABLISHED分布
ss -tn state established | awk '{print $5}' | cut -d: -f2 | sort | uniq -c | sort -rn | head
# 4. 查看每个IP的连接数
ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
# 5. 如果某个IP连接数异常,可能在攻击
# 查看具体连接
ss -tn | grep "1.2.3.4"
# 6. 应对措施:
# - 封禁异常IP
iptables -I INPUT -s 1.2.3.4 -j DROP
# - 调整TIME_WAIT重用
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
# - 调整最大连接数
echo 4096 > /proc/sys/net/core/somaxconn
内核参数调优:
# /etc/sysctl.conf 添加
# TIME_WAIT重用(客户端)
net.ipv4.tcp_tw_reuse = 1
# TIME_WAIT超时时间(默认60秒)
net.ipv4.tcp_fin_timeout = 30
# 允许孤儿socket数量
net.ipv4.tcp_max_orphans = 262144
# TCP buffer自动调优
net.ipv4.tcp_rmem = 4096 87380 6291456
net.ipv4.tcp_wmem = 4096 65536 6291456
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# 连接队列
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
# 应用配置
sysctl -p
工具9:curl + 常用网络诊断
场景问题
需要测试HTTP接口是否正常,想看响应头和响应时间。DNS解析对不对,CDN是否生效,想模拟各种HTTP请求。
工具介绍
curl是命令行里最常用的HTTP工具,支持各种协议和各种选项。不只是发请求,还能做认证、Cookie、文件上传下载、代理等。
核心用法
HTTP请求:
# GET请求
curl https://example.com
# GET请求,显示响应头
curl -i https://example.com
# GET请求,只显示响应头
curl -I https://example.com
# 显示请求和响应头(调试用)
curl -v https://example.com
# 显示更详细的信息(包括证书、版本等)
curl -vv https://example.com
# 跟随重定向
curl -L https://example.com
# 保存到文件
curl -o /tmp/output.html https://example.com
# 下载文件(自动用原文件名)
curl -O https://example.com/file.tar.gz
# 不显示进度条
curl -s -O https://example.com/file.tar.gz
POST请求:
# POST表单数据
curl -X POST -d "username=admin&password=123456" https://example.com/login
# POST JSON数据
curl -X POST -H "Content-Type: application/json" \
-d '{"username":"admin","password":"123456"}' \
https://example.com/api/login
# 带认证的POST
curl -X POST -u user:pass \
-d "data=value" \
https://example.com/api
# 文件上传
curl -X POST -F "file=@/tmp/test.txt" https://example.com/upload
# 设置自定义头
curl -H "Authorization: Bearer token123" \
-H "X-Custom-Header: value" \
https://example.com/api
高级用法:
# 限速下载(100KB/s)
curl --limit-rate 100k -O https://example.com/largefile.tar.gz
# 最大下载时间
curl -m 30 -O https://example.com/file # 30秒超时
# 连接超时(比-m更细粒度)
curl --connect-timeout 10 -I https://example.com
# 使用代理
curl -x http://proxy.example.com:8080 https://example.com
# 使用Cookie
curl -b "session=abc123" https://example.com/api
# 保存Cookie到文件
curl -c /tmp/cookies.txt https://example.com/login
# 读取Cookie文件
curl -b /tmp/cookies.txt https://example.com/api
# 跳过证书验证(测试用)
curl -k https://example.com(测试用,不推荐生产用)
# 指定TLS版本
curl --tlsv1.2 https://example.com
# 指定CA证书
curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com
实用脚本:
#!/bin/bash
# http_health_check.sh - HTTP健康检查脚本
check_http() {
local url=$1
local name=${2:-$url}
local expected_code=${3:-200}
# 获取状态码和响应时间
response=$(curl -o /dev/null -s -w "%{http_code}|%{time_total}|%{size_download}" \
--connect-timeout 5 -L "$url")
code=$(echo $response | cut -d'|' -f1)
time=$(echo $response | cut -d'|' -f2)
size=$(echo $response | cut -d'|' -f3)
if [ "$code" = "$expected_code" ]; then
echo "[OK] $name - HTTP $code - ${time}s - ${size}bytes"
return 0
else
echo "[FAIL] $name - Expected $expected_code, got $code - ${time}s"
return 1
fi
}
# 使用示例
check_http "https://example.com" "主站" "200"
check_http "https://example.com/api/health" "API健康检查" "200"
check_http "https://example.com/static/test.js" "静态资源" "200"
check_http "https://example.com/notexist" "404测试" "404"
DNS调试:
# 查看DNS解析过程(配合watch)
watch -n 1 'dig example.com +short'
# 模拟DNS查询
dig @8.8.8.8 example.com
# 只查看Answer部分
dig example.com +short
# 查看完整DNS记录
dig example.com ANY
# 查看MX记录
dig example.com MX
# 反向DNS查询
dig -x 93.184.216.34
# 批量检查域名解析
for domain in example.com google.com github.com; do
ip=$(dig +short $domain)
echo "$domain -> $ip"
done
CDN/CDN效果验证:
# 查看响应头(判断CDN)
curl -I https://example.com
# 常见CDN响应头:
# Cloudflare: cf-ray, cf-cache-status
# Akamai: x-akamai-transformed, server
# CloudFront: x-cache, via
# 阿里云CDN: x-swift-optimized, x-oss
# 对比直连和CDN
# 直连IP
dig +short example.com
# 回源测试
curl -H "Host: example.com" http://<origin_ip>/
# 检查缓存状态
curl -I https://example.com/static/file.js
# 看 Age: 表示CDN缓存了多少秒
# 看 x-cache-hit 表示命中缓存
工具10:systemctl + journalctl – 服务与日志管理
场景问题
服务起不来了,想看启动失败的原因。服务运行正常但响应慢,想看实时日志。想查看某个时间段的历史日志。服务重启了,想知道是谁触发的、为什么。
工具介绍
systemctl是systemd服务的控制工具,用来启动、停止、重启、查看服务状态。journalctl是systemd日志查看工具,比传统的/var/log更强大,支持按时间、按服务、按级别过滤。
核心用法
systemctl基本操作:
# 查看服务状态
systemctl status nginx
# 启动服务
sudo systemctl start nginx
# 停止服务
sudo systemctl stop nginx
# 重启服务
sudo systemctl restart nginx
# 重新加载配置(不中断连接)
sudo systemctl reload nginx
# 查看服务是否运行
systemctl is-active nginx
# 查看服务是否开机启动
systemctl is-enabled nginx
# 设置开机启动
sudo systemctl enable nginx
# 禁用开机启动
sudo systemctl disable nginx
# 重新加载systemd配置
sudo systemctl daemon-reload
# 查看所有运行的服务
systemctl list-units --type=service --state=running
# 查看所有失败的服务
systemctl --failed --type=service
journalctl基本操作:
# 查看所有日志(从最早开始)
sudo journalctl
# 从最新开始查看
sudo journalctl -e
# 实时跟踪日志
sudo journalctl -f
# 查看特定服务的日志
sudo journalctl -u nginx
# 查看特定服务的错误日志
sudo journalctl -u nginx -p err
# 日志级别:emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6), debug (7)
# 按时间过滤
sudo journalctl --since "2026-05-11 10:00:00"
sudo journalctl --since "1 hour ago"
sudo journalctl --since today
sudo journalctl --since yesterday
sudo journalctl --since "2026-05-01" --until "2026-05-02"
# 查看上次启动的日志
sudo journalctl -b -1
# 查看指定boot ID的日志
sudo journalctl --list-boots
sudo journalctl -b abc123def456
# 查看磁盘占用
sudo journalctl --disk-usage
# 清理旧日志(保留最近7天)
sudo journalctl --vacuum-time=7d
# 清理到指定大小
sudo journalctl --vacuum-size=500M
# 按行数限制
sudo journalctl --vacuum-files=5
组合使用技巧:
# 查看服务启动失败原因
sudo systemctl status nginx
sudo journalctl -u nginx -p err --no-pager -n 50
# 查看服务是否被人手动重启
sudo journalctl -u nginx --since "1 day ago" | grep -E "Started|Stopping|Started"
# 查看某命令的执行历史
sudo journalctl --since "1 hour ago" | grep "nginx"
# 查看内核日志(dmesg)
sudo journalctl -k
# 查看所有 critical 级别的日志
sudo journalctl -p crit
# 实时查看某服务的错误
sudo journalctl -u nginx -p err -f
# 统计各服务日志大小
for svc in nginx mysql redis; do
size=$(sudo journalctl -u $svc --since "30 days ago" 2>/dev/null | wc -c)
echo "$svc: $(($size/1024/1024))MB"
done
服务管理进阶:
# 查看服务的依赖关系
systemctl list-dependencies nginx
# 查看服务被谁依赖
systemctl list-dependencies --reverse nginx
# 查看服务资源限制
systemctl show nginx | grep -E "Memory|Limit"
# 修改服务资源限制(临时)
sudo systemctl set-property nginx MemoryLimit=512M
# 查看服务启动时间
systemctl show nginx -p ActiveEnterTimestamp
# 查看服务的进程
systemctl status nginx
# 或
ps aux | grep nginx
# 查看服务配置
systemctl cat nginx
# 查看服务完整配置(包括默认配置)
systemctl show nginx
故障排查示例:
# 场景:nginx服务启动失败
# 1. 查看服务状态
sudo systemctl status nginx
# 2. 查看详细日志
sudo journalctl -u nginx -p err --no-pager -n 100
# 3. 测试配置文件
sudo nginx -t
# 4. 如果是端口被占用
sudo lsof -i :80
# 5. 杀死占用进程
sudo kill $(sudo lsof -t -i :80)
# 6. 重新启动
sudo systemctl restart nginx
# 7. 验证
sudo systemctl status nginx
curl -I localhost
# 场景:mysql服务自动停止
# 1. 查看服务状态
sudo systemctl status mysql
# 2. 查看什么时候停的、为什么停的
sudo journalctl -u mysql --since "1 day ago" | grep -E "Stopping|Started|Killed|OOM"
# 3. 查看是否是OOM被kill
sudo journalctl -k | grep -i "oom"
dmesg | grep -i "oom"
# 4. 查看资源限制
systemctl show mysql | grep -E "Memory|Limit"
# 5. 如果是OOM,查看内存使用峰值
sudo journalctl -u mysql --since "1 day ago" | grep -i "memory"
# 6. 解决方案:
# - 增加内存
# - 优化MySQL内存配置(减少innodb_buffer_pool_size)
# - 添加swap
# - 设置OOM优先级
总结:工具组合使用示例
场景:Web服务器响应慢综合排查
#!/bin/bash
# web_slow_diagnose.sh - Web响应慢综合排查脚本
echo "=== Web服务器响应慢排查 ==="
echo "开始时间: $(date)"
# 1. 初步诊断:系统资源
echo ""
echo "--- CPU和内存 ---"
top -b -n 1 | head -20
echo ""
free -h
# 2. 查看网络连接状态
echo ""
echo "--- 网络连接统计 ---"
ss -s
# 3. 查看TIME_WAIT数量
echo ""
echo "--- TIME_WAIT分析 ---"
echo "TIME_WAIT数量: $(ss -tn state time-wait | wc -l)"
echo "ESTABLISHED数量: $(ss -tn state established | wc -l)"
# 4. 查看端口连接分布
echo ""
echo "--- TOP连接IP ---"
ss -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -10
# 5. 查看进程CPU/内存占用
echo ""
echo "--- TOP进程 ---"
ps aux --sort=-%cpu | head -15
# 6. 查看磁盘IO
echo ""
echo "--- 磁盘IO ---"
iostat -xcz 1 5 2>/dev/null | tail -20
# 7. 查看nginx日志(最近的错误)
echo ""
echo "--- Nginx错误日志 ---"
tail -20 /var/log/nginx/error.log
# 8. 查看PHP-FPM状态(如有)
if systemctl is-active php-fpm >/dev/null 2>&1; then
echo ""
echo "--- PHP-FPM状态 ---"
curl -s localhost/status | head -20
fi
# 9. 查看后端连接(如使用proxy)
echo ""
echo "--- 后端服务状态 ---"
curl -s localhost/health 2>/dev/null || echo "health endpoint不可用"
echo ""
echo "=== 排查完成 ==="
场景:数据库连接问题排查
#!/bin/bash
# db_connection_diagnose.sh - 数据库连接问题排查
echo "=== 数据库连接问题排查 ==="
# 1. 查看连接数
echo ""
echo "--- MySQL连接统计 ---"
mysql -e "SHOW STATUS LIKE 'Threads_connected';"
mysql -e "SHOW STATUS LIKE 'Max_used_connections';"
mysql -e "SHOW VARIABLES LIKE 'max_connections';"
# 2. 查看当前连接
echo ""
echo "--- 当前连接 ---"
mysql -e "SHOW FULL PROCESSLIST\G" | grep -E "Command|State|Info" | head -50
# 3. 分析连接状态
echo ""
echo "--- 连接状态分布 ---"
mysql -e "SHOW FULL PROCESSLIST\G" | grep "Command:" | sort | uniq -c | sort -rn
# 4. 分析连接来源
echo ""
echo "--- 连接IP分布 ---"
mysql -e "SHOW FULL PROCESSLIST\G" | grep "Host:" | awk -F: '{print $1}' | cut -d' ' -f2 | sort | uniq -c | sort -rn | head -10
# 5. 查看慢查询
echo ""
echo "--- 慢查询 ---"
mysql -e "SHOW GLOBAL STATUS LIKE 'Slow_queries';"
# 6. 查看锁等待
echo ""
echo "--- 锁等待 ---"
mysql -e "SELECT * FROM information_schema.INNODB_LOCK_WAITS\G" 2>/dev/null || echo "无锁等待"
# 7. 查看系统资源
echo ""
echo "--- 系统IO ---"
iostat -xcz 1 5 2>/dev/null | tail -15
# 8. 查看临时表使用
echo ""
echo "--- 临时表使用 ---"
mysql -e "SHOW GLOBAL STATUS LIKE 'Created_tmp%';"
附录:工具速查表
| 工具 | 用途 | 常用命令 |
|---|---|---|
| htop | 交互式进程监控 | htop, htop -u user, htop -t |
| atop | 综合系统监控 | atop, atop -r /var/log/atop/xxx |
| iotop | 进程级IO监控 | iotop -b -o, iotop -b -u user |
| nethogs | 按进程网络流量 | nethogs eth0 |
| ncdu | 磁盘使用分析 | ncdu /, ncdu -x / |
| strace | 系统调用追踪 | strace -p PID, strace -c command |
| lsof | 打开的文件 | lsof -i :80, lsof -p PID |
| tcpdump | 网络抓包 | tcpdump -i eth0 port 80 -w file.pcap |
| netstat/ss | 网络连接 | ss -tn, ss -s, ss -tnp |
| curl | HTTP诊断 | curl -v, curl -I, curl -X POST |
| journalctl | 系统日志 | journalctl -u svc -f, journalctl --since today |
文档信息
- 版本:1.0
- 更新日期:2026-05-11
- 适用系统:RHEL/CentOS 7/8/9,Ubuntu 18.04/20.04/22.04
- 适用场景:Linux服务器日常运维

本文链接:https://www.yunweipai.com/49274.html





网友评论comments