线上服务器出问题的时候,老板在催、客户在催、监控系统告警邮件在响。值班工程师打开终端那一刻,所有人的目光都盯着屏幕。如果你只会 cd /var/log,然后 grep error,再然后 tail -f,很容易就卡死在一个低效的死循环里。
老鸟和初级工程师之间的真正差距,不是命令记住了多少,而是脑子里有没有一张"该用哪个命令去看什么现象"的网络图。同一台出问题的服务器,初级同学可能折腾半个钟头没碰到根因,老鸟只需要 30 秒到 5 分钟就能完成"现象 → 指标 → 假设 → 命令验证 → 落点定因"的闭环。
本文不打算整一份语法字典,也不打算把所有选项列出来。我们直接进实战:把一线工程师日常常用的 30 个排查命令按场景归类,每条命令都说清楚——为什么用它、用它看什么、看到什么算正常、看到什么算异常、拿到异常后下一步去哪。
全文命令在 CentOS 7+/Ubuntu 20.04+、kernel 4.18+/5.4+、systemd 主流版本上验证过;不同发行版的输出格式可能略有差异,但关键字段含义一致。如果你的内核不一样,重点关注的几个 /proc、/sys 路径和指标名不会变。
下文 30 个命令覆盖 CPU、内存、磁盘 IO、磁盘空间、网络、进程、文件/句柄、内核/系统、日志/审计、用户/权限、容器、压测/基准这 12 大场景,几乎覆盖了一次完整故障定位所需要的全部终端武器。
在动手之前,先梳理两条贯穿全文的主线。后面所有命令只是工具,真正决定定位速度的是这两条主线在脑子里能不能转起来。
主线一:分层。先看系统层、再看进程层、再看文件/网络层。
top、vmstat、iostat、sar、mpstat、free、dmesg。这一层负责回答"机器整体资源是什么状态"。pidstat、pstree、ps、strace、lsof、pmap、perf。这一层负责回答"哪条进程在消耗资源、对哪些内核资源有依赖"。lsof +D、fatrace、inotifywait、ss、netstat、tcpdump、iftop、nethogs、ethtool。这一层负责回答"正在读写什么、正在和谁通信"。lsns、nsenter、unshare -p -- ...、cat /proc/$pid/cgroup、ctr -t docker containers ls、crictl ps。这一层负责回答"这是不是名字像进程、实际上是个独立的命名空间"。主线二:证据链。每一个结论都要有命令输出做依据。
老鸟写事故复盘时,最讨厌的就是"经查是 CPU 过高导致的请求超时"这种没营养的话。真正有用的结论是:“16:02:03 时 pidstat -u 1 60 显示 Java 进程 1984 的 %usr 长期 > 95%,对应时段 vmstat 1 中 r 列稳定在 32+,而机器为 32 核,因此判定为 CPU 资源耗尽;同时 perf top -g 显示 __pthread_mutex_lock 占 28%,最终确定是 GC 锁竞争热点”。
证据链比结论本身更重要。复盘不是讲故事,复盘是把命令输出和结论对上的过程。
接到一个"服务慢"的告警时,不要立刻扎进进程,先把下面这套快速排查模板跑完。
第一步:5 秒看全局。 远程登录,先敲三个不破坏性的命令:
bash uptime
free -h
df -h
uptime 看 load average;free -h 看内存、缓存、Swap;df -h 看磁盘。这一步的目的是 30 秒内建立对机器的整体感性认知:是满载运行还是基本空闲?这台机器看起来"正常"还是"非常态"?
第二步:30 秒看内核与告警。 立刻看内核日志,最近有没有 OOM、硬件错误、磁盘 full、IP 冲突等关键事件:
bash dmesg -T | tail -200
journalctl -p err -S "1 hour ago"
内核日志里通常能找到"机器最近有没有出过严重事件"的答案。如果出现 Out of memory: Killed process 1984 就直接断案;如果出现 I/O error, dev sda, sector 123456,磁盘已经坏了,先救数据。
第三步:1 分钟看 CPU/内存/IO 三个走向。 跑一组采样命令:
bash vmstat 1 10
iostat -dx 1 10 2>/dev/null || iostat 1 10
pidstat -u 1 5
观察曲线变化:CPU 是稳态高?还是尖峰?是用户态高还是内核态高?r 列、b 列、%util、await 分别是什么表现?
第四步:5 分钟定位进程/线程。 一旦在某一项指标上看到异常,跟着异常往下挖:
pidstat -u -p $pid 1 5、top -Hp $pid、perf top -p $pidpmap -x $pid | sort -n -k2 | tail -20、/proc/$pid/smaps、/proc/$pid/status 中的 VmRSS、VmSwapiotop -oP、pidstat -d 1 5 -p $pid、lsof -p $pid | grep REGiftop -i eth0、nethogs、ss -tan state established | head第五步:横向对比。 如果多实例集群上只有一台慢,就需要横向对比正常实例和异常实例的命令输出,比如 /proc/cpuinfo、内核版本、磁盘队列长度、网络中断数。
第六步:留证。 命令输出保存到 /tmp/<server>-<time>.log,命令本身保存到 ~/.bash_history 或脚本文件里,方便事后复盘。复盘不是写总结,是回放你能拿到的证据。
接下来进入 30 命令详解部分,每条命令都按这个结构展开:为什么用 → 命令 → 预期 → 异常 → 判断 → 下一步。
top —— 全局概览目的: 拿到系统最核心的 CPU 与内存全景,确定是否有进程吃满 CPU。
命令:
bash top -d 1 -b -n 1 | head -50
# 交互式只刷一次,-d 1 表示刷新间隔,-b 用于把输出落到日志里
预期输出:load average: 1.20, 1.05, 0.88 这种相对平稳的小数;CPU 行 us/sy/wa 不会同时破 50%。
异常表现:
> 90% CPU,且 RES(驻留集)大、状态长时间 R,是典型 CPU 热点load averager 列(正在运行的线程数)同样走高,是真正的 CPU 资源紧张waiostat 的 %util 一起看,是 IO 等待st判断逻辑: 想快速区分 CPU 高/内存高/IO 高,靠 top 单屏就能完成 us、sy、wa、hi、si 五块。再用 top -Hp $pid 切到线程层,看具体线程。
下一步动作: 找到吃满 CPU 的 PID 之后,到 A5 用 pidstat,再到 A6 用 perf。
htop —— 比 top 友善得多的增强版目的: 看到树状进程关系、niceness、VIRT/RES/SHR、command 全行;交互式按 F6 按字段排序。
命令:
bash htop -d 5
# 或 dstat 插件模式
htop --tree
预期输出: 树状分组清晰,能看到 systemd → sshd → bash → htop 这种父子关系;CPU 柱状条带颜色标识用户态/内核态。
异常表现: 鼠标点击交互比 top 简洁很多(如果装了 lsof、strace 插件可以直接在进程上 F2 唤起)。
判断逻辑: 当你希望减少"按哪个键"的记忆负担时,htop 比 top 上手快很多。在不允许用鼠标的纯文本终端,退回 top。
下一步动作: 与 A1 互替使用;htop 看进程树更直观,top 在嵌入式/极简 SSH 终端能跑。
vmstat —— 系统综合快照目的: 1 秒级采样,统计系统态/用户态、内存、IO、中断、上下文切换。
命令:
bash vmstat 1 10
输出头部:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 8123456 12345 987654 0 0 1 12 567 1234 8 2 88 2 0
预期输出:
rbsi/sobi/boiostat 看 IO 流量incs(上下文切换)在合理量级us + sy + wa + id = 100异常表现:
rtop 拿不到空闲核bsi/so > 0cswaid判断逻辑:vmstat 的关键是看 r、b、bi/bo、si/so、CPU 状态五块。这五条线交叉在一起基本能盖住 70% 的资源定位。
下一步动作: CPU 异常转 A5 pidstat;IO 异常转场景 C;上下文切换异常转 Java GC 排查。
mpstat —— 多核 CPU 维度目的: 把 CPU 状态按每颗核拆开看。
命令:
bash mpstat -P ALL 1 5
预期输出: 每个 CPU 都显示 usr、nice、sys、iowait、irq、soft、steal、guest、gnice、idle。
异常表现:
usr 高、另一些核空闲:进程没有合理绑定到多核(CPU 亲和性)iowait 异常高:磁盘中断集中在这颗核irq判断逻辑:mpstat -P 0 1 5 单独看 P0 这一颗核,能快速判断进程是不是被绑定在某一颗核上。
下一步动作: 多核分配不均时考虑 taskset 设置亲和性;iowait 高跳到场景 C。
pidstat —— 进程/线程级 CPU/IO/上下文切换目的: 比 top 精度更高的"按 PID 看每秒 CPU 占用"。
命令:
bash pidstat -u -p 1984 1 5
pidstat -w -p 1984 1 5
pidstat -d -p 1984 1 5
预期输出(CPU):UID PID %usr %system %guest %wait %CPU CPU Command;正常情况下 %CPU 应 < 100(单核)。
异常表现:
%CPU > 100:多核机器上吃满多核%waitpidstat -wcswch/s 飙升、nvcswch/s 很低:主动 context switch 暴涨(比如 GC)pidstat -dkB_rd/s / kB_wr/s 突然变大:进程在猛读/写判断逻辑:pidstat 是 top 的子版本,但能输出 CPU + IO + 上下文切换三个视角的统一字段。线上事故复盘时这是必出场的命令。
下一步动作: CPU 热点用 top -Hp $pid 拿到线程 tid,然后 printf '%x\n' $tid 拿十六进制去 /proc/$pid/task/$tid/stack 看内核栈或 jstack。
perf —— 性能采样与热点定位目的: 拿到 CPU 热点调用栈,快速识别"哪个函数在烧 CPU"。
命令:
bash perf top -p $(pgrep -n nginx) -n 30
# 或采样 10 秒,统计热点函数
perf record -F 99 -p $(pgrep -n java) -g -- sleep 10
perf report -n --stdio | head -50
预期输出: 函数按占用 CPU 时间倒序。
异常表现:
gc_task、evacuation_run、compress_pages、json_encode 等__softirq_entry、__do_softirq、net_rx_action、ext4_*:网络/IO 中断处理烧 CPU判断逻辑: 同一个进程分别在 usr 和 sys 的占比,决定下一步策略。us 高说明业务热点;sy 高说明系统调用或锁竞争。
下一步动作: 用户态热点给开发;内核态热点查网络/磁盘/中断;Java 进程可以 async-profiler + perf 混合采样。
sar —— 历史数据回放目的: 拿到系统历史 CPU/内存/网络指标。
命令:
bash sar -u 1 5
sar -r 1 5
sar -n DEV 1 5
sar -b 1 5
预期输出: 以表格形式回放过去指定秒数的数据。
异常表现: 在没装 sysstat 的机器上命令会缺失,需要 apt install sysstat 或 yum install sysstat 并开启 ENABLED="true"。
判断逻辑: 装 sysstat 后,它会按 /etc/cron.d/sysstat 每 10 分钟采样一次,存入 /var/log/sa/saXX。老板问"昨天 16:30 出了什么事",你只要 sar -s 16:00:00 -e 17:00:00 -f /var/log/sa/sa11 就能直接答出。
下一步动作: 数据查询出来后画图;推荐 +sadf -g 或 ksar 等工具。
free —— 内存与 Swap目的: 一眼看可用内存、Buffer/Cache、Swap。
命令:
bash free -h
free -m | awk 'NR==2{printf "Used: %s MB / Total: %s MB (%.2f%%)\n", $3, $2, ($3/$2)*100}'
预期输出:
total used free shared buff/cache available
Mem: 62Gi 24Gi 12Gi 0Gi 25Gi 36Gi
Swap: 2.0Gi 0Gi 2.0Gi
availablefree + buff/cache - 不可回收free 很低但 available 高,说明缓存了文件,写完会自动让出异常表现:
availablebuff/cache 也变 0:物理内存真的耗尽Swapused > 0:已触发换页free -s 2free 单调下行:进程在持续吃内存(疑似泄漏)判断逻辑:available 才是真正能用的内存。内核会动态把 buff/cache 让给进程,所以 available 趋零才有意义。
下一步动作: 内存真不够 → B2、B3 找吃内存的进程;Swap 大 → C 场景查 IO;内存泄漏 → valgrind --tool=massif、pidstat -r、Go pprof。
slabtop —— 内核 slab 分配器目的: 找到内核自己偷偷吃内存的位置,如 dentry、inode、网络 socket buffer。
命令:
bash slabtop -d 5 -s c
预期输出: 按缓存对象大小倒序:dentry、inode_buffers、vm_area_struct、skbuff_head_cache、task_struct、anon_vma_chain 等。
异常表现:
dentrykmalloc-1ksock_inode_cachess -s判断逻辑: 当 free 看着没事但 buff/cache 巨大,且 available 紧张时,就需要怀疑 slab。
下一步动作:slabtop -o 看对象 cache,必要时 slabstats.py、诊断驱逐模块。
pmap —— 进程内存分布目的: 看进程内部分段,分清是堆大还是 mmap 大还是栈大。
命令:
bash pmap -x $(pgrep -n java) | sort -n -k3 | tail -20
cat /proc/$(pgrep -n java)/smaps_rollup
预期输出: 标记 [ anon ]、[ stack ]、[ heap ]、[ mmap ]。pmap -x 会额外展示 PSS、Dirty。
异常表现:
[ heap ]判断逻辑:PSS 比 RSS 更能反映多进程共享内存的占比。
下一步动作: 拿到进程号丢 gdb -p $pid info proc mappings,或 jcmd $pid VM.native_memory summary(Java 进程专属)。
iostat —— 块设备指标目的: 真正的 IO 指标都在这里:r/s、w/s、rkB/s、wkB/s、aqu-sz、%util、await、rareq-sz、wareq-sz。
命令:
bash iostat -dx 1 10
iostat -dxz 1 5 2>/dev/null | head -20
# 输出列:Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await rareq-sz wareq-sz aqu-sz %util
预期输出:
%utilawaitaqu-sz1.0 已经在排队异常表现:
%util%utilaqu-sz 也高,IO 在排队await判断逻辑:iostat 是 IO 排查命令族里的"主战武器"。必须 -dx 输出扩展统计(-x 不一定够,加 -d);把 -N 也加上,按 LVM/DM 名称输出。
下一步动作: 高 await/%util 持续 → C2 iotop 找进程;NVMe 顶上限 → 业务侧降量或加盘。
iotop —— 进程级 IO目的: 看哪条进程在猛 IO。
命令:
bash iotop -oPa -d 3 -n 3
-o 只显示有 IO 的进程;-P 只显示进程而非线程;-a 累计 IO;-d 刷新间隔;-n 采样次数。
预期输出:
Total DISK READ : 0.00 B/s | Total DISK WRITE : 256.00 K/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 123.00 K/s
PID PRIO USER DISK READ DISK WRITE COMMAND
1984 be/4 mysql 0.00 B/s 128.00 K/s /usr/sbin/mysqld
异常表现:
write 行持续几 MB/s:binlog 风暴或 redo 写满java 进程:典型 flush 操作cptar/dd 出现:外部任务判断逻辑:iotop 看到进程后,用 lsof -p $pid | grep REG 拿到具体文件。
下一步动作: 业务进程 → 跳到 pidstat -d 进一步采样;外部任务 → 等任务结束或挪到空闲窗口。
pidstat -d —— 进程级读写速率目的:iotop 一次性刷新,pidstat -d 能落日志、做趋势。
命令:
bash pidstat -d 1 5 -p $(pgrep -n mysqld)
预期输出:
12:00:01 kB_rd/s kB_wr/s kB_ccwr/s Command
12:00:02 0.00 64.00 0.00 mysqld
异常表现:kB_wr/s 翻倍往上跑,结合 MySQL 的 Innodb_data_writes 趋势,可以判断是 redo/undo 还是 binlog。
下一步动作: 与 MySQL Performance Schema 接口对账。
df —— 文件系统占用目的: 看每个挂载点的占用。
命令:
bash df -h
df -i
df -hT
# T 输出文件类型(ext4/xfs/overlay 等)
# i 输出 inode 使用率
预期输出:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 18G 30G 38% /
/dev/sdb1 500G 120G 380G 24% /data
异常表现:
/var/lib/docker 已经 100%:容器写不了东西Use% = 100%avail = 0:建议立刻 du 排查判断逻辑: 容器场景特别容易出现"父挂载点没满,但 overlay 满"。两种情况都查 inode 和 block。
下一步动作: 满 → D2/D3/D4 找到占用大头。
du —— 目录占用目的: 看哪个目录大。
命令:
bash du -sh /var/log
du -h --max-depth=1 / 2>/dev/null | sort -h | tail -10
du -h --max-depth=1 /var/lib/docker/volumes | sort -h
预期输出: 占用从小到大排列。
异常表现:du -h --max-depth=1 /tmp 发现 /tmp 几十 GB:常是某个应用没在清理临时文件。
判断逻辑:du 走递归,慢,但准确性高。线上大文件系统慎用全盘 du /。
下一步动作: 配合 D3 lsblk 确认块设备大小,定位要不要扩盘。
lsblk —— 块设备树目的: 看分区、LVM、挂载点映射。
命令:
bash lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,ROTA,MODEL
# ROTA=1 表示 HDD,=0 表示 SSD/NVMe
预期输出:
NAME SIZE TYPE FSTYPE MOUNTPOINT ROTA MODEL
sda 100G disk / 1 /dev/sda
├─sda1 50G part ext4 / 1
├─sda2 300G part ext4 /data 1
nvme0n1 1.0T disk (mounted)
├─nvme0n1p1 16G part ext4 /boot 0
└─nvme0n1p2 1.0T part ext4 /opt 0
异常表现:MOUNTPOINT 显示 (mounted) 但上层未挂载,可能是 LUKS 或 device-mapper。
判断逻辑: 看硬盘类型 + 是否被 LVM 包,对扩容规划直接成图。
下一步动作: 扩容 → 配合 lvm / growpart 或 xfs_growfs、resize2fs。
ncdu —— 交互式 du目的: 大目录 console 可视化巡检。
命令:
bash ncdu -x / # -x 跨文件系统不统计
预期输出: 类似 top 风格的交互界面,方向键进入子目录。
异常表现:ncdu 在生产环境慎用,因为 du 类操作扫描慢。但挂在一个专门用于巡检的 minion 上很合适。
判断逻辑: 替代 du 时更直观;没有 ncdu 时用 du -ah 2>/dev/null | sort -h | tail -50。
下一步动作: 输出靠 man 摸索一次快捷键即可上手。
ss —— Socket 统计目的: 看 TCP/UDP 连接、状态统计。
命令:
bash ss -s
ss -tan state established | head
ss -tan state time-wait | wc -l
ss -ltnp
ss -ltnp | grep ':80\b'
预期输出:
TCP: 100 (estab) 50 (closed) 1024 (orphan) 1500 (timewait) ...
timewait 多但 estab 正常:正常的连接关闭,无问题。
异常表现:
orphantimewaitestabss -sTCP sockets in use + ... 接近 net.core.somaxconn:系统级 listen backlog 满判断逻辑:ss -ltnp 看监听端口及哪个进程在 listen。ss 比 netstat 拿数据快 10 倍以上(netstat 在大连接数时很慢)。
下一步动作:timewait 多 → 开启 tw_reuse;orphan 多 → 排查为什么没有调用 close。
netstat —— 端口 / 路由 / 旧字段目的: 看老问题、看路由表(虽然现代人都用 ip)。
命令:
bash netstat -tnp
netstat -lnp
netstat -i
预期输出:Recv-Q / Send-Q 队列深度。
异常表现: 监听队列 Recv-Q 持续 > 0:积压。
判断逻辑: 在新版本机器(kernel > 5.4)推荐 ss 取代 netstat,但 netstat -i 看网卡流量波峰仍然好用。
下一步动作:Recv-Q 积压 → 应用层调 listen backlog。
ip —— 网络栈全能命令目的: 取代 ifconfig、route、arp,看 IP / 路由 / VRF / 桥接。
命令:
bash ip -br addr
ip -br link
ip -s link show eth0
ip route
ip rule
预期输出:
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 10.0.0.5/24 fe80::...
异常表现: 看到 eth0 报错 state UP 但 addr 中丢 IP:DHCP 续约失败或手动配错。
判断逻辑:ip -s link 不仅看 state 还看丢包、错误包。
下一步动作: 丢包 → 跳到 E8 ethtool。
tcpdump —— 抓包目的: 拿真实流量去解业务问题,比如"健康检查为什么没响应"。
命令:
bash tcpdump -nn -s 0 -i eth0 -w /tmp/cap.pcap 'tcp and src host 10.0.0.5 and port 80'
tcpdump -nn -i any port 80 # 在线概览
tcpdump -nn -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'# 只看 SYN/FIN
预期输出: 在终端打印大量行。
异常表现:tcpdump -nn -c 100 -i eth0 没抓到任何包:网卡未上行、容器网卡或镜像环回错。
判断逻辑:tcpdump 是网络方向定位"为什么这事儿没发生"的杀手锏。它能证明包到了还是没到、是否被防火墙拦了、链路层是否丢包。
下一步动作: 拿到 pcap 后用 Wireshark 或 tcpdump -r 二次分析;DNS 异常用 tcpdump -nn -i any port 53。
iftop —— 网卡维度进出流量目的: 看哪台远程主机在跟本机通信最多。
命令:
bash iftop -i eth0 -n -P -B
# -n 不解析 DNS
# -P 显示端口
# -B 以 Byte 为单位
预期输出: 上下行表格。
异常表现: 某 IP 上下行 100Mbps 起步,配合 nethogs 抓进程能定位被谁打了。
判断逻辑: 不算精确,但能告诉你"流量大体在和谁通信"。
下一步动作: 找到 IP 后 nethogs/ss -tan | grep $ip 验证。
nethogs —— 进程级网络流量目的: 看哪条进程在用流量。
命令:
bash nethogs -d 3 eth0
预期输出: 进程名列、Tx/Rx Kbps。
异常表现: 容器内 PID 名字看起来像 python3,流量跑满:是异常的数据外发或下载任务。
判断逻辑:nethogs 在多核/多队列网卡上需要 -d 拉大刷新间隔避免读到全 0。
下一步动作: 对违规进程要立即冻结或隔离。
mtr —— 路由 + 丢包 + 时延目的: 看 ping 的逐跳表现,比 traceroute 多了丢包统计。
命令:
bash mtr -rwbzc 100 8.8.8.8
# -r 报告模式
# -w 不解析主机名
# -b 显示 IP/Host 双向
# -z 显示 AS
# -c 100 跑 100 跳
预期输出: 平均 Loss%、Avg、StDev、Best、Wrst、Last。
异常表现: 第 N 跳开始丢包 N% 但第 N-1 跳丢包 0:丢包点就在第 N 跳。
判断逻辑:mtr 比 traceroute 实用在它能看到"哪一跳真正丢包",而 traceroute 一次性 ICMP 不够稳。
下一步动作: 把截图或 mtr -j -c 100 $host 输出 JSON 提交工单。
ethtool —— 网卡驱动与协商目的: 看协商速率、丢包、驱动固件版本。
命令:
bash ethtool eth0
ethtool -S eth0 | grep -i drop
ethtool -k eth0 | grep -E 'rx|tx|tcp-seg'
预期输出:
Settings for eth0:
Speed: 10000Mb/s
Duplex: Full
Port: Twisted Pair
Auto-negotiation: on
异常表现:
droprx checksum offload判断逻辑: 网卡问题最早表现都是协商速率掉到非满速。
下一步动作: 协商异常 → 查链路两端、网线、交换机;丢包 → 调 ring buffer、txqueuelen、开启 tcp-segmentation-offload。
ps —— 进程快照目的: 一行命令拿到进程列,包括 PID、PPID、C、STIME、CMDLINE。
命令:
bash ps -eo pid,user,pri,ni,pcpu,pmem,stat,etime,cmd | head -50
ps -eo pid,ppid,cmd --forest
# auxf 老树形
ps auxf | grep -E 'ssh|nginx|mysql'
预期输出:STAT 列是 R+ 进程正在 R 状态前台,S 是睡眠,D 不可中断睡眠(IO 等待),Z 僵尸。
异常表现:
D 状态进程:磁盘 IO 阻塞Z 僵尸:父进程没调用 wait,常是 CI/CD 容器跑完没清理判断逻辑:ps -eo ... 是固定字段筛选的核心用法,比 ps aux | grep 更可控。
下一步动作: 找到 PID 后接 F2、I5。
pstree —— 进程树目的: 看父子关系,自动收缩 PID 链。
命令:
bash pstree -aps $$ # 当前终端所在进程树
pstree -aps 1984 # 指定 PID
预期输出: 树形,缩进表父子关系。
异常表现: 进程树很深但是某叶子不停重启:脚本里写错了要追根因。
判断逻辑: 在容器内 pstree 很直观看 PID 1 是 systemd 还是别的进程。
下一步动作: 找最终没清理 PID 的孤儿 → lsof -p $orphan_pid 验证它实际在做啥。
strace —— 系统调用级跟踪目的: 跟踪一个进程的所有系统调用,看它读什么、写什么、卡在哪。
命令:
bash strace -p $(pgrep -n nginx) -tt -s 200 -o /tmp/nginx.strace
strace -T -tt -p 1984 -e trace=network 2>&1 | head -200
预期输出: 大量 recvfrom()、write()、阻塞点。
异常表现:
futex 系统调用:锁竞争热点epoll_wait 没事件:代码 bug 上层不活跃判断逻辑:strace 看清"进程为什么不来回"非常有用,但生产环境高负载慎用,可能让进程慢几倍。
下一步动作:strace -c -p $pid 看调用次数统计;网络 hang 转 tcpdump。
lsns —— Linux namespace目的: 看容器、嵌套容器的命名空间。
命令:
bash lsns -t pid
lsns -t net
lsns -t mnt
预期输出: 每行 NS 类型、NSID、PID、USER、COMMAND。
异常表现: 同名进程有不同的 PID NSID:容器化后发生。要进入容器除了 docker exec,也可以 nsenter -t $pid -n -m -i -u -p 直接进。
判断逻辑:lsns 是 lsof、pstree 的进阶补充,当 PID 居然找不到对应业务时排查 namespace 泄露。
下一步动作: 进 nsenter 之后用 ip a、ss -tan 看网络栈。
lsof —— 一切皆文件目的: 看哪条进程打开了哪些文件、socket、管道、设备、共享库。
命令:
bash lsof -i :80 # 看哪个进程占用了 80
lsof -u mysql # MySQL 用户打开的所有句柄
lsof -p 1984 # 进程内句柄
lsof +D /data # 递归看谁打开了 /data 下文件
lsof /var/log/messages # 谁在用这个日志
预期输出: 标准输出能筛名字、PID、fd、type。
异常表现:
/var/lib/kubelet 拖大FIFO 管道未关闭:日志失活或批量处理崩判断逻辑:lsof 是排查"为什么删了文件没释放"最直接的命令。
下一步动作: 拿到 PID 后用 lsof -p $pid 看文件详情。
lsof +D —— 目录级文件占用目的: 看哪些文件正在被某目录下的进程访问。
命令:
bash lsof +D /data/logs
预期输出: 进程列表 + 文件路径。
异常表现:/data/logs 删除不了却被 lsof 显示一个打开,是常规问题。
下一步动作:fuser -uv /data/logs 替代或协同 lsof。
fatrace —— 文件访问事件目的: 类似 inotifywait 的全局视角,可以看到全系统所有文件系统事件。
命令:
bash fatrace -c -t
# -c 输出访问类型(open/read/modify)
# -t 加时间戳
预期输出:mysqld(1234): R /data/mysql/ibdata1 / nginx(2345): W /var/log/nginx/access.log。
异常表现: 配合 iotop 能拿到"哪条文件被猛写"的事实证据。
下一步动作: 改名 fatrace -t -f O | grep ... 之类过滤。
inotifywait —— 单目录事件目的: 看某一目录的文件创建、修改、删除事件。
命令:
bash inotifywait -mr /var/log/nginx
# -m 持续监听,不退出
# -r 递归
预期输出: 多行 / CREATE / MODIFY / DELETE。
异常表现: 频繁出现 MODIFY 之后又 DELETE:典型日志滚动没生效。
下一步动作: 对接 logrotate 的 postrotate,触发 reload。
dmesg -T —— 内核日志目的: 看内核最近事件,硬件、内存、磁盘、CPU、网络都汇报。
命令:
bash dmesg -T | tail -50
dmesg -T -l err,warn,emerg,alert # 只看错误级
预期输出: 带时间戳的内核日志。
异常表现:
Out of memory: Killed processpgmajfault:OOM killI/O error, dev sda, sector 123456TCP: out of memory -- consider tuning tcp_memIPv4: martian source下一步动作: OOM → B 场景;磁盘坏 → D 场景;TCP 内存压力 → 跳到网络。
uname —— 内核版本目的: 拿到内核版本号、CPU、架构。
命令:
bash uname -a
cat /etc/os-release
预期输出:Linux web-1 5.15.0-89-generic #99-Ubuntu ... 这种。
下一步动作: 配合 hiera/role/profile 或 hostnamectl 确认机器角色。
uptime —— 启动时间 + load目的: 5 秒看完机器启动持续时间、用户数、负载。
命令:
bash uptime
预期输出:15:30:02 up 200 days, 1 user, load average: 1.20, 1.05, 0.88
异常表现:load 远超核数,意味着 CPU 资源紧张。
下一步动作: 配合 nproc、lscpu 知道几核。
lscpu —— CPU 信息目的: 模型、核数、超线程、NUMA。
命令:
bash lscpu
lscpu | grep -E 'CPU\(s\)|NUMA|MHz|Hz'
预期输出: 多 NUMA 时多 node。
下一步动作: 多 NUMA 时考虑 numactl 调亲和性。
journalctl —— systemd 日志目的: 看到 service 的所有日志。
命令:
bash journalctl -u sshd -S "1 hour ago"
journalctl -u nginx --since yesterday --until"1 hour ago"
journalctl -p err -b # 本次启动以来 error
journalctl _PID=1984 # 进程日志
journalctl -u kubelet -o short-iso -f # 实时
预期输出: 带颜色时间戳的事件。
异常表现:Failed to start、Connection refused、(code=exited, status=1/FAILURE) 等待。
下一步动作: 配合 coredumpctl list 看核心转储。
journalctl --verify —— 日志完整性目的: 验证 systemd 日志完整性,磁盘空间紧张后日志被截断的判断。
命令:
bash journalctl --verify
journalctl --disk-usage
下一步动作:/var/log/journal 满 → 调 SystemMaxUse、MaxRetentionSec。
logrotate —— 日志轮转目的: 通过 /etc/logrotate.conf 控制日志不被撑爆。
命令:
bash cat /etc/logrotate.d/nginx
logrotate -d /etc/logrotate.d/nginx # -d 试运行,不动文件
logrotate -f /etc/logrotate.d/nginx # -f 强制执行
预期输出: 试运行报告每个动作。
下一步动作: 改规则走变更窗口,带回滚(保留一份 cp 出来的 backup)。
id / whoami —— 当前用户目的: 排查操作是否用了对的人、对的 sudo。
命令:
bash id
whoami
sudo -n -l 2>/dev/null | head# 能 sudo 什么
下一步动作: 拿到能 sudo 的清单,不在清单里就联系管理员。
lastb / last —— 登录日志目的: 看哪些用户最近登录成功/失败。
命令:
bash lastb | head -50 # 登录失败
last | head -50 # 登录成功
last -i # IP 形式
下一步动作:lastb 数量爆炸:暴力破解行为。
getfacl / setfacl —— ACL目的: 看 linux ACL 设置,权限与 chmod 不一致就靠 ACL。
命令:
bash getfacl /etc/shadow
setfacl -m u:work:r-- /etc/ssh/sshd_config
setfacl -dm u:work:rwX /opt/logs
下一步动作: 常用结合 umask、chmod 一起做更细粒度权限控制。
ctr / crictl —— 容器运行时客户端目的: 跟 Containerd / CRI-O 沟通。
命令:
bash ctr -n k8s.io containers list
ctr -n k8s.io images list
crictl ps -a # 容器运行时
crictl logs $container_id
下一步动作: 联同 kubectl describe pod 排查。
docker stats —— 容器实时资源目的: 看到容器级 CPU、内存、网络、IO。
命令:
bash docker stats --no-stream
docker stats $container 1
下一步动作: 配合 docker top $container 拿到 PID 在宿主机上的映射,再做宿主机命令排查。
unshare / nsenter —— 进命名空间排查目的: 不用进容器内部直接在宿主机上用宿主命令看容器内的情况。
命令:
bash PID=$(docker inspect -f '{{.State.Pid}}'$container)
nsenter -t $PID -n -m -i -u -p -- /bin/bash
下一步动作:nsenter -t $PID -n ss -tan 比 docker exec + ss 更能看完整视角。
dd —— 顺序 IO 性能目的: 用单条命令测块设备顺序读写速度。
命令:
bash ddif=/dev/zero of=/tmp/test.bin bs=1M count=1024 oflag=direct 2>&1
ddif=/tmp/test.bin of=/dev/null bs=1M iflag=direct 2>&1
预期输出:1073741824 bytes (1.1 GB) copied, 6.123 s, 175 MB/s。
风险提醒:dd of=/dev/sda 极危险,绝对禁止;写临时文件 of= 一定要路径正确,oflag=direct 绕开 page cache。
下一步动作: 测试完 rm /tmp/test.bin,或保留作为下一次对比样本。
fio —— 灵活 IO 压测目的: 灵活用 IO 场景:顺序写、随机写、混合读写、QD 深度。
命令:
bash fio --name=randwrite --ioengine=libaio --direct=1 \
--filename=/tmp/fio.bin --size=1G --bs=4k \
--rw=randwrite --numjobs=4 --runtime=30 --time_based=1 \
--iodepth=32 --group_reporting
预期输出: 表格报告 IOPS、带宽、延迟 P99。
风险提醒:fio 一定要写独立目录下的独立文件,不要打到业务目录;--size 不要超过可用空间的 80%。
下一步动作: 拿到 slat/clat 历史后画出 latency 分布。
下面这张表把上面 30 个命令的"目标、对照现象、命令、关键指标"压缩成一行,方便值班时打印贴在工位旁边。
topuptime / htop | pidstat | |||
vmstat 1 | iostatpidstat | |||
mpstat -P ALL 1 | taskset | |||
pidstat -u 1 | perf top -p | |||
perf top -p | ||||
sar -u -s 16:00:00 | ||||
free -h | pmap | |||
slabtop | /proc/slabinfo | |||
pmap -x | gdb | |||
iostat -dx 1 | iotop | |||
iotop -oP | pidstat -d | |||
pidstat -d | ||||
df -hT | du | |||
du -sh | ncdu | |||
lsblk | ||||
ncdu | ||||
ss -tan state | tcpdump | |||
netstat -i | ethtool | |||
ip -s link | ethtool | |||
tcpdump -i any | ||||
iftop -i eth0 | nethogs | |||
nethogs eth0 | ss -tan | grep | |||
mtr -r -c 100 | ||||
ethtool -S eth0 | ||||
ps -eo ... | pidstat | |||
pstree -aps | lsof | |||
strace -p | ||||
lsns | nsenter | |||
lsof -i :80 | fuser | |||
lsof +D /path | ||||
fatrace -c | inotifywait | |||
inotifywait -m | ||||
dmesg -T | ||||
uname -a | ||||
lscpu | numactl | |||
journalctl -u | coredumpctl | |||
journalctl --verify | ||||
logrotate -d | ||||
lastb | ||||
getfacl | ||||
crictl ps | kubectl | |||
docker stats | nsenter | |||
nsenter -t | ip a | |||
dd | fio | |||
fio |
/etc/sysctl.d/99-base.conf排查这套工具的本身不需要特别配置;但要让背后 /proc、/sys 给我们更全的信息,可以加以下项:
text kernel.core_pattern = /var/lib/coredumps/core.%e.%p.%t
kernel.printk_ratelimit = 0
kernel.printk_ratelimit_burst = 200
kernel.softlockup_all_cpu_backtrace = 1
kernel.warn_umount_after = 0
fs.epoll.max_user_watches = 4194304
fs.file-max = 2097152
net.core.somaxconn = 4096
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
加载:sysctl --system。
/etc/ssh/sshd_config 优化日志排查 SSH 暴力破解时让 sshd 自身把 verbose 拉到合适等级:
text LogLevel VERBOSE
MaxAuthTries 6
MaxSessions 10
LoginGraceTime 30s
/etc/systemd/journald.conf排查 /var/log 满日志不能写:
text Storage=persistent
SystemMaxUse=8G
SystemKeepFree=2G
MaxRetentionSec=90day
重启:systemctl restart systemd-journald。
/etc/rsyslog.conf(可选)如果用 rsyslog 上传审计日志:
text module(load="imuxsock")
module(load="imjournal")
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
*.* /var/log/syslog
auth.* /var/log/auth.log
cron.* /var/log/cron.log
~/.bashrc 个人快捷组合值班用的常用 alias:
bash alias t1='top -d 1 -b -n 1 | head -50'
alias vm1='vmstat 1 10'
alias io1='iostat -dx 1 10'
alias mp1='mpstat -P ALL 1 5'
alias du1='du -h --max-depth=1 $1 | sort -h'
alias ipa='ip -br -c addr'
alias ss1='ss -tan state established | head'
alias tcp1='tcpdump -nn -s 0 -i any -c 100 port 80'
alias hit='echo -e "$(date +%Y-%m-%d\ %H:%M:%S) -- $(hostname) -- uptime: $(uptime)"'
值班要看 5 类日志,再加上 5 个核心系统指标。
5 类日志:
/var/log/kmsg、dmesg -T、/var/log/syslog(Ubuntu)、/var/log/messages(CentOS)。/var/log/auth.log(Ubuntu)、/var/log/secure(CentOS)。/var/log/nginx/*.log、/var/log/mysql/error.log、/var/log/redis/redis.log。/var/log/audit/audit.log(auditd 后)。INFO/WARN/ERROR。5 类指标:
top、mpstat、pidstat -u、%usr/%sys/%wait。free -h 的 available、/proc/meminfo 的 MemAvailable、/proc/vmstat 的 pgpgin、pgpgout、pgfault、pgmajfault。iostat -dx 的 r/s、w/s、rkB/s、wkB/s、aqu-sz、await、%util。/proc/net/dev、sar -n DEV、ifconfig 的 TX/RX、网卡 drops 计数。/proc/$pid/status 的 VmRSS、VmSwap、Threads。观察动作:
sar 或 node_exporter 落时序;/proc/loadavg、/proc/meminfo、/proc/stat、/proc/diskstats 都能直接 cat。把 30 命令装到决策树里,才是真正的排查模板。下图给出"机器出现’慢’的现象"时的一条线性决策路径。
text service slow
|
+----------------------------+
| 系统层 5 秒 | top / free / df / uptime / dmesg |
+----------------------------+
|
+------------------+------------------+
| |
资源明显异常 资源无明显异常
| |
进入资源定位树 进入组件定位树
| |
+--------+-------+--------+-------+ |
| | | | | |
CPU IO 内存 网络 磁盘空间 ------------------------------------+
| | | | | | |
A 场景 C 场景 B 场景 E 场景 D 场景 Web / API / DB / MQ 三个组件视角 |
pidstat iotop pmap ss du 入口各自应用日志+指标 |
perf pidstat slabtop tcpdump ncdu ------------------------------------+
| | | | |
+-------+--------+-------+ |
| |
假设→验证(多次循环) |
| |
修复→验证→回滚→复盘 |
排查方法学:
针对 30 命令中几个高风险操作,必须提前告知读者:
dddd if=/dev/zero of=/dev/sda 直接清空磁盘。永远加 oflag=direct 与 bs 控制,写测试盘前 ls -l /dev/sd? 反复确认。find / -deletefind -print 先看路径列表,二次确认后再加 -delete。rm -rf /data/*trash-put 或 mv 到带日期的备份目录。iotoppidstat -d -p 用在高 IO 机器上可能额外增加 1% – 5% IO 负载,避免长时间观测。strace -p-e trace=file 限制。tcpdump -w /tmp/cap.pcap/tmp/cap.pcap 也加密、清理时 shred -u $file 或 srm $file。dmesgkernel.printk 调到 console 容易打满屏幕改成 0。pkill -9 javakill -9kill -SIGTERM 再升级到 kill -SIGKILL。lsof +D /datatimeout 10 lsof +D ... 限定时间。fio--filename=/path/test/,避免打到业务目录。判定排查是否结束,按以下顺序验证:
/tmp/<host>-<time>.log;下面是一个最小验证脚本示例,记住:脚本里所有命令都要 set -euo pipefail:
bash #!/usr/bin/env bash
set -euo pipefail
LOG_DIR="/tmp/health-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$LOG_DIR"
echo"[$(date +%T)] collecting..." | tee -a "$LOG_DIR/collect.log"
top -d 1 -b -n 5 | tee"$LOG_DIR/top.log"
vmstat 1 5 | tee"$LOG_DIR/vmstat.log"
iostat -dx 1 5 | tee"$LOG_DIR/iostat.log"
free -h | tee"$LOG_DIR/free.log"
df -hT | tee"$LOG_DIR/df.log"
ss -s | tee"$LOG_DIR/ss.log"
dmesg -T | tail -200 | tee"$LOG_DIR/dmesg.log"
journalctl -p err -S "1 hour ago" --no-pager | tee"$LOG_DIR/journalctl.log"
echo"[$(date +%T)] done. logs in $LOG_DIR"
风险提醒:脚本默认写到 /tmp,可能因为开机时被清空。建议落地到 /var/log/health-$(hostname)/ 并用 logrotate。
排查行为本身大多无副作用,但凡操作必须配套回滚。下面给出易踩坑动作的回滚清单:
dd if=... of=...of= 立刻停掉 Ctrl+C + fuser -k /dev/sdX + 重新分区恢复。find /var/log -name '*.gz' -delete-delete,改成 find ... -print | head + 手动 rm 一个 + shred。pkill -9 redisredis-cli shutdown nosave,数据先 AOF/RDB 落地。iptables -I INPUT -p tcp --dport 22 -j DROPiptables-save > /etc/iptables.bak,失联立刻 reboot 进单用户恢复。sysctl -w vm.dirty_*=.../etc/sysctl.d/*.conf,回滚改回注释 + sysctl --system。tc qdisc ...tc qdisc del dev eth0 root,重启 net ns 会重置。chmod -R 777 /etcchmod 600 /etc/shadow + /etc/sudoers 修复 pkexec、auth。整体回滚原则:
bash -x 跑一遍看执行流;restore.sh,用 set -ex 严格跑回。cp /etc/... /etc/...bak-$(date +%s);iptables、sysctl、磁盘格式化、dd、fio 必须有第二人在场;canary 节点的别一次性动到所有机器;bash -n script.sh、shellcheck script.sh、man $cmd 永远靠谱;script -t -r $time.log -c $cmd,script 能记录完整交互;一线运维最常做的不是写炫技的命令堆,而是把已知 30 个命令按场景组装成一条"机器慢"快速定位流水线:
uptime、free、df、dmesg、top、vmstat。mpstat、iostat -dx、pidstat。lsof、ps、strace、perf、pstree。ss、netstat、ip、tcpdump、mtr、ethtool。journalctl、lastb、logrotate 配置。ctr/crictl、docker stats、nsenter。30 个命令不是 30 个独立的工具,是 30 个拼图块。每个工程师要把它们在脑子里组成一张二维表:横轴是问题现象,纵轴是这条现象可能要查的指标与命令。当机器出现一个新的现象时,在脑子里把这条轴往右拖,找到对应的列,拿出对应的命令执行。
成熟的工程师不是记住了 30 命令,是把 30 命令之间的关系看明白了。下一次再遇到问题,你会发现自己不再"按顺序敲命令",而是按"我现在需要确认 X 信息,所以打命令 Y"。
值班不在命令行数多少,定位准确、回滚完整、复盘有据,才是真的。
为了方便读者把 30 命令内化,下面提供几张速查表。
A1. 按"一秒钟能拿到的事实"分组:
top -bn 1uptime、free -h、df -hss -tan state established | headvmstat 1 5、iostat -dx 1 5A2. 按"指标名 -> 命令"映射分组:
top、mpstat、pidstat -u、sar -ufree、slabtop、pmap、sar -riostat、iotop、pidstat -d、fioss、netstat、tcpdump、ip、ethtoolps、pstree、strace、lsns、nsenterlsof、fatrace、inotifywaitdmesg、uname、uptime、lscpujournalctl、lastb、logrotateA3. 按"机器的层级"分组:
lscpulsblk、ethtool、smartctl | ||
sysctldmesg、lsns、uname | ||
uptimetop、free、vmstat、iostat、mpstat | ||
pspidstat、pstree、lsof、pmap、strace、perf | ||
lsof +Dfatrace、inotifywait | ||
ssnetstat、ip、tcpdump、iftop、nethogs、mtr、ethtool | ||
crictlctr、docker stats、nsenter | ||
mysql -eredis-cli、journalctl -u |
A4. 按"应急优先级"分组:
dmesg、iostat、lsblktop、pidstat、lsofvmstat、iostat、sartop、free、df、uptimelastb、journalctl、auditd把这张速查图记在脑子里,每次出事就不容易卡壳。
下面是这一篇与各篇文章中频繁出现的高风险命令清单。读者需要按公司流程给每条命令配套审批、备份、双人复核:
rm -rf | trash-putcp -a 到备份盘 | ||
find / -delete | -print | ||
truncate /var/log/X | cp -a | ||
DROP DATABASE | mysqldump | ||
TRUNCATE TABLE | mysqldump | ||
KILL -9 <pid> | |||
systemctl restart <svc> | systemctl start | ||
sysctl -w ... | sysctl -w | ||
iptables -F | iptables-save | iptables-restore | |
docker rm -f | |||
docker volume rm | |||
kubectl delete pod | kubectl apply | ||
kubectl delete pvc | |||
tc qdisc ... | tc qdisc del | ||
chmod -R 777 /etc |
每条红线配置相应的审批流程:变更单、风险评估、回滚演练、双人复核、变更窗口、上线验收。
一线工程师在值班时要会"临场思考":当一个告警来临,先冷静 30 秒,再打命令。
text 思考流程:
1. 我听到 / 看到的是什么现象?
2. 我对当前机器有什么"健康"基线认识?
3. 我能用什么命令把"现象 + 基线"对比出来?
4. 我需要看哪几个指标?
5. 这些指标走向告诉我是什么问题?
命令执行流程:
1. 防御性观察(不破坏现状)
2. 进一步深入(缩小范围)
3. 假设与验证
4. 修复
5. 回滚准备
把"思考 + 命令"结合。每打一条命令前都问一句"我现在想要确认什么?“。每打一条命令后问一句"输出告诉我什么?下一步是什么?”
避免常见的错误:
cat /var/log/... 然后 tail -ftop -bn 1 看了又说 “看不出问题”kill -9 处理为了便于记忆,把 30 命令放到几个真实场景里。
场景:Java 应用响应时间上升。
top -bn 1free -hvmstat 1 5iostat -dx 1 5pidstat -u -p $JAVA_PID 1 5jstack $JAVA_PID > /tmp/jstack.txtpmap -x $JAVA_PID | sort -n -k3 | taillsof -p $JAVA_PID | grep REGss -tan | grep $JAVA_PID场景:磁盘盘满告警。
df -hTdu -h --max-depth=1 /data | sort -hncdu -x /datalsof +D /datajournalctl --vacuum-time=2dfind /var/log -type f -size +500M -name '*.gz'场景:网卡带宽满。
sar -n DEV 1 5ip -s link show eth0ss -tan state established | wc -lnethogs eth0tcpdump -nn -c 100 port 443把场景练习熟,到值班就"手熟"了。
下面是 30 个命令的常用组合:
E1:CPU 高 + 内存高 + 线程多 → Java GC 风暴
bash top -bn 1
pidstat -u 1 5
pidstat -w 1 5
jstat -gc $JAVA_PID 1 5
jstack $JAVA_PID
E2:CPU 高 + await 高 + %util 高 → MySQL checkpoint
bash vmstat 1 5
iostat -dx 1 5
iotop -oPa -d 3 -n 1
mysql -e "SHOW ENGINE INNODB STATUS\\G" | sed -n '/FILE I\/O/,/LATEST DETECTED DEADLOCK/p'
E3:丢包 + drops 多 + 应用 hang → 网卡 / 网线
bash ip -s link show eth0
ethtool -S eth0 | grep drop
dmesg -T | grep -i eth0
E4:连接空 + 端口 listen 不上 → backlog 满 / conntrack 满
bash ss -ltnp | head
ss -s
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
E5:机器响应整体慢 → 路由器 / 内核 / KVM
bash top -bn 1
vmstat 1 5
iostat -dx 1 5
ping server01 -c 5
mtr -r server01
每个组合都对应一类故障模式。组合拳熟了,故障定位一目了然。
下面列几条发行版差异:
F1:CentOS vs Ubuntu 文件位置差异
F2:常用包名差异
F3:默认内核参数差异
CentOS / Ubuntu 多数 sysctl 默认值一样,但 vm.swappiness、kernel.sched_latency_ns 略有差异。生产环境应统一内核参数文件。
F4:容器化发行版
Atomic / Fedora CoreOS / Bottlerocket 是专门为容器设计的发行版,使用 rpm-ostree 模式管理包。这种机器上 dnf 类命令可能不可用,应以 rpm-ostree status 代替。
把 30 命令与故障树对齐,遇到故障能"按树分支定位"。
text 机器故障
|
+--------------+--------------+
| | |
性能慢 服务挂 资源满
| | |
+----+--+----+----+ | +----+---+----+
| | | | | | | | |
CPU IO 内存 网卡 进程 服务 磁盘 内存 容器
下面对每个分支给出"用哪些命令"指引:
mpstat、pidstat -u、perf topiostat、iotop、pidstat -dfree、slabtop、pmapip -s、ethtool、tcpdumpps、pstree、stracejournalctl -u、ss、dmesgdf、du、ncducrictl、docker stats、nsenter把"故障树和命令"映射记牢,定位反应时间会大幅下降。
下面给出一段可重复运行的脚本,专门安装"运维排查工具箱"。
bash #!/usr/bin/env bash
set -euo pipefail
# 通用工具
ifcommand -v apt-get; then
apt-get update
apt-get install -y htop iotop sysstat dstat strace lsof \
tcpdump mtr-tiny net-tools ethtool nethogs iftop \
curl wget jq sysbench fio
elifcommand -v yum; then
yum install -y epel-release
yum install -y htop iotop sysstat strace lsof tcpdump \
mtr net-tools ethtool nethogs iftop curl wget jq sysbench fio
fi
# perf
ifcommand -v apt-get; then
apt-get install -y linux-tools-common linux-tools-$(uname -r)
fi
ifcommand -v yum; then
yum install -y perf
fi
echo"tools ready"
脚本风险:必须使用 sudo 提升权限;建议公司内部镜像源;避免安装时报错。
最后把 30 命令与一些企业实践对齐。
I1:CI/CD 中的命令使用
CI/CD pipeline 里常需要 curl、jq、tr、sed、awk、ps、grep。比如:
curl ... | jq '...'awksedps -ef | grep这些命令在流水线中运行,但仍然是同一套 OS 工具。
I2:监控中的命令使用
Zabbix / Prometheus 通过 ssh + 命令采集数据。例如:
bash iostat -dx 1 1 | awk 'NR>3 {print $1, $4, $14}'
定期采集,结果上送到 Prometheus / Zabbix。
I3:自动化编排中的命令使用
Ansible / SaltStack / Puppet 通过 SSH 执行命令。每个命令都是上面 30 命令的子集;可见"30 命令"是企业自动化的"根命令集"。
I4:安全审计中的命令使用
lastb、last、grep、journalctl、auditctl、auditd。都已经在 30 命令里。
把 30 命令与"CI/CD、监控、自动化、安全" 4 个企业实践对齐,价值最大化。
30 个 Linux 排查命令不是顶层命令的拼凑,而是覆盖 CPU、内存、磁盘 IO、磁盘空间、网络、进程、文件/句柄、内核/系统、日志/审计、用户/权限、容器、压测基准 12 大场景的命令集合。每一个命令都从"目的 → 命令 → 预期输出 → 异常表现 → 判断逻辑 → 下一步动作"展开。
读者按这篇文章学习后:
老鸟不是因为记住了全部命令,而是命令背后的概念体系。把这套体系熟悉到能讲给新人,你就是真正的一线老鸟。
把这篇文章完整读两遍,再背 3-5 遍,对应你公司的环境演练一次,下次再遇到问题,你会发现,原来要慌半小时的问题,现在只需要一杯茶的时间搞定。
到这里文章正文 + 10 个附录已经覆盖完整的"30 个 Linux 排查命令"主题。读者可以根据文中表格快速找出对应命令、按场景记忆组合、按步骤走完整排查流程。
最后一句送给大家:
好的工程师不是命令记得多,而是看现象就知道该用什么命令。 现象 + 命令 + 指标,3 个东西训练到匹配。等你看到任何告警都能快速想到"我先打哪条命令",你就已经成为团队里让人敬佩的那一位。
K1. 老版本与新版本的差异
许多命令在过去十年里有了变化。读者在使用时需要注意:
iostatiostat 1 10(默认 -d)到现代 iostat -dx 1 10vmstattop 类被 htop、btop 取代netstatss 取代ifconfigip 取代routeip route 取代cat /proc/net/tcpnetstat -t 的另一种途径K2. 命令族 vs 子命令
许多命令族是父子结构,下面列举几个常见族:
ipip a、ip r、ip linkbtrfssystemctlsystemctl list-units、systemctl statusjournalctljournalctl -u、journalctl --sincenmclinmcli con、nmcli devcrictlcrictl pods、crictl ps、crictl images掌握一个命令的"族",远比掌握一个命令有用。
K3. 跨平台命令
docker 和 containerd 不完全是同一套命令族:
docker psdocker exec、docker stats、docker topctr -n k8s.io containers listctr -n k8s.io tasks list、crictl ps、crictl exec运维要熟练其一,并知其二;防止调度告警时找不到正确的客户端。
下表是常见 Prometheus 指标与命令字段的对照:
node_cpu_seconds_total | mpstat -P ALLusr/sys/iowait/idle |
node_memory_MemAvailable_bytes | free -havailable |
node_memory_MemFree_bytes | free -hfree |
node_memory_Buffers_bytes | free -hbuff/cache |
node_memory_Cached_bytes | free -hbuff/cache |
node_filesystem_avail_bytes | df -hTavail |
node_disk_read_bytes_total | iostat -dxrkB/s |
node_disk_written_bytes_total | iostat -dxwkB/s |
node_disk_io_now | iostat -dxaqu-sz |
node_load1 | uptime1-min-load |
node_network_receive_bytes_total | ip -s linkRX bytes |
node_network_transmit_bytes_total | ip -s linkTX bytes |
node_netstat_TCP_CurrEstab | |
node_exporter_textfile_sshd | |
process_cpu_seconds_total | pidstat -u%CPU |
process_open_fds |
读者用同一张表做"监控指标 ↔ 命令输出"的对照,把两者关联起来。当 Prometheus 抓不到数据时,能立刻知道应该走命令去验证。
新型监控工具如 Vector / Telegraf / OpenTelemetry,采集函数往往基于:iostat/vmstat/pidstat 等命令的输出。
例如在 Vector 中:
toml [sources.iostat]
type = "exec"
command = ["iostat", "-dx", "1", "5"]
这条配置让 Vector 直接调用 iostat。当我们懂命令,配置监控工具时也会更顺畅。
把 30 命令设计成企业内部新人培训。每周一题,每人一题。
text 本周问题:
1. 客户反馈"页面打不开"。请用 5 条命令定位。
2. CPU 飙高至 95%。请写出排查命令清单。
3. 内存剩余 5%。请写出内存热点排查方法。
4. 磁盘 IO 拉满。请写出排查路径。
5. 网络丢包 5%。请写出网络排查命令。
让新人每周练习 5 个真实场景下的命令组合。30 命令就能内化为肌肉记忆。
把团队"老鸟"经验沉淀为"30 命令 + 实操场景",一次又一次重复,分人能背得下。这条是企业软实力的体现。
把 30 命令的输出标准化归档:
bash #!/usr/bin/env bash
set -euo pipefail
NAME=$(hostname -s)
TS=$(date +%Y%m%d-%H%M%S)
DIR="/var/log/ops-snapshot/$NAME"
mkdir -p "$DIR"
exec > "$DIR/$TS.log" 2>&1
echo"== boot =="
date
uptime
echo"== top =="
top -d 1 -b -n 1 | head -50
echo"== memory =="
free -h
echo"== disk =="
df -hT
echo"== vmstat =="
vmstat 1 5
echo"== iostat =="
iostat -dx 1 5
echo"== ps -eo =="
ps -eo pid,user,pri,ni,pcpu,pmem,stat,etime,cmd --sort=-pcpu | head -30
echo"== ss =="
ss -s
ss -tan state established | head
echo"== lsof =="
lsof -i :80 2>/dev/null | head
echo"== dmesg =="
dmesg -T | tail -100
echo"== sysctl vm =="
sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_expire_centisecs \
vm.dirty_writeback_centisecs
echo"== scheduler =="
for d in /sys/block/*/queue; do
echo"$d: $(cat $d/scheduler)"
done
echo"== done =="
风险:脚本默认落在 /var/log/ops-snapshot/<hostname>/,需要先用 mkdir -p 创建并赋权限。
长期积累 30 命令的输出,能得到一份性能基线:
text 机器 load CPU% mem-avail io-util net-pps
server1 0.8 15% 32G 12% 1k
server2 1.2 25% 28G 25% 2k
server3 0.5 10% 48G 8% 500
这是健康基准。下一次发现某台机器 io-util 90%(远超基线 12%),就立刻进入排查。
性能基线需要:
建立性能基线是值班的"早期检测"基础。
到这里所有附录已经覆盖了命令、风险、组合、场景、版本、版本差异、新监控、运维、技术审校、企业实践、培训、复盘。读者可以根据自己所在团队的需求选用对应章节。
最后一句话:
把"30 命令"作为一个起点——把命令、场景、基线、监控、培训这 5 个维度都建立起来,就能让自己从一个会敲命令的工程师,转变为能用命令驱动团队能力升级的资深一线老鸟。这是每一个运维 / DevOps 工程师成长的"硬件价值 + 软件价值"双轮驱动。
写到这里已经到结尾。从"为什么要写这篇文章"开始,到"命令清单 + 实战 + 验证 + 风险 + 培训 + 复盘"完整闭环,全文给了读者一个完整的"30 命令知识地图"。
希望你能把这篇文章收藏起来,每遇到一个真实问题,就回到对应章节看一眼。这种"问题 - 命令 - 思路"相互映射的训练,是工程师从初阶走向中阶、再到资深的关键路径。
最后送所有读者一句话:
会打命令只是一线工作的下限,把命令和"思考 + 验证 + 协作"联动起来,才是上限。 把 30 命令用得熟练,每次故障面前,你都可以以一线的工程师身份,做出有理、有据、有回滚的专业响应。
祝大家每一次值班都顺利,每一次定位都精准,每一次复盘都清楚。


今天给大家分享一份超级牛掰的Linux学习笔记,足足有1456页!是一位Linux运维大佬整理分享的,分享是获得大佬同意的,大家有需要的尽管收藏起来!
这份笔记非常全面且详细,从Linux基础到shell脚本,再到防火墙、数据库、日志服务管理、Nginx、高可用集群、Redis、虚拟化、Docker等等,与其说Linux学习笔记,不如说是涵盖了运维各个核心知识。
并且图文并茂,代码清晰,每一章下面都有更具体详细的内容,十分适合Linux运维学习参考!






扫描下方二维码,回复暗号“1456页Linux笔记“,即可100%免费领取成功
