Skip to content

Linux 进阶命令与排障 · 一、通用排障框架至八、磁盘与 I/O 排查 ​

返回分篇目录

先按通用框架保存现场,再从故障剧本选择具体检查。需要操作细节时直接进入 systemd、CPU/内存、磁盘 或 网络;排障记录模板用于保存结论。

Linux 进阶命令与排障 ​

先按通用框架保存现场,再从故障剧本选择具体检查。需要操作细节时直接进入 systemd、CPU/内存、磁盘 或 网络;排障记录模板用于保存结论。

一、通用排障框架 ​

建议按以下顺序处理:

  1. 定义现象:谁受影响、什么请求失败、从何时开始、是否可稳定复现。
  2. 确认环境:主机、容器、区域、版本、配置和依赖,避免查错对象。
  3. 判断范围:单实例、单节点、单可用区还是全局。
  4. 检查近期变化:发布、配置、证书、依赖、容量和权限。
  5. 按层验证:资源 → 进程 → 端口 → DNS/网络 → TLS → 应用 → 下游。
  6. 先止损再修复:止损动作也要记录影响、验证方式和回滚条件。

采集一次带时间戳的主机概览:

bash
date --iso-8601=seconds
hostname
uptime
free -h
df -hT
df -ih
systemctl --failed
ss -s

不要仅凭一次快照下结论。性能问题至少比较正常基线和异常窗口,并区分负载升高是原因还是结果。

二、可靠的 Shell 管道 ​

2.1 退出码和 pipefail ​

bash
<command>
echo "$?"                   # 0 通常表示成功,非 0 表示不同失败

set -o pipefail
<producer> | <consumer>
pipeline_status=$?

脚本常用严格模式:

bash
#!/usr/bin/env bash
set -Eeuo pipefail
选项作用注意
-e未处理的失败使脚本退出条件、子 Shell 等语义需理解后使用
-u读取未定义变量时报错可选变量要用 ${VAR:-}
pipefail管道任一环节失败即失败防止上游错误被末端成功掩盖
-EERR trap 在函数等范围继承仍不能替代显式错误处理

2.2 xargs 的空输入和特殊字符 ​

bash
find <directory> -type f -print0 | xargs -0 -r sha256sum

-print0 与 -0 能正确处理空格、换行等文件名;GNU xargs -r 在空输入时不执行命令。变更操作前先把末端命令换成 printf '%s\n' 检查目标。

2.3 tee 同时显示和保存 ​

bash
set -o pipefail
<command> 2>&1 | tee <capture-file>

若输出包含 Token、请求体、用户数据或配置秘密,不应直接保存到普通文件;先脱敏并设置访问权限。

三、排序、去重、连接与字段提取 ​

bash
cut -d: -f1 /etc/passwd         # 按分隔符取字段
sort <file>                     # 排序
sort -u <file>                  # 排序并去重
uniq -c                         # 对相邻重复行计数,通常先 sort
paste <file-a> <file-b>         # 按行合并
comm -12 <sorted-a> <sorted-b>  # 两个已排序文件的交集
join <sorted-a> <sorted-b>      # 按键连接两个已排序文件
tr '[:lower:]' '[:upper:]'      # 字符转换

统计日志中最常见的客户端地址:

bash
awk '{print $1}' <access-log> | sort | uniq -c | sort -nr | head -n 20

生产日志格式可能含代理链、JSON 或带空格字段,先抽样确认字段定义,不要机械使用 $1、$9。

四、sed、awk 与 jq 结构化处理 ​

4.1 sed:流式筛选和替换 ​

bash
sed -n '10,30p' <file>          # 输出 10 到 30 行
sed -n '/BEGIN/,/END/p' <file>  # 输出两个模式之间内容
sed 's/<old>/<new>/g' <file>    # 只输出替换结果,不修改文件

就地修改前先生成差异:

bash
sed 's/<old>/<new>/g' <file> > <candidate-file>
diff -u <file> <candidate-file>

sed -i

sed -i 会直接修改文件,且 GNU/BSD 参数存在差异。重要配置应先备份、验证候选文件,再用原子替换或配置管理工具发布。

4.2 awk:按记录计算 ​

bash
# 逗号分隔,打印第 1、3 列
awk -F, '{print $1, $3}' <file.csv>

# 对第 2 列求和并输出平均值
awk '{sum += $2; n++} END {if (n) print sum, sum/n}' <file>

# 只输出第 5 列大于 100 的记录
awk '$5 > 100 {print NR, $0}' <file>

按 HTTP 状态码统计:

bash
awk '{count[$9]++} END {for (code in count) print code, count[code]}' <access-log> | sort

4.3 jq:JSON 查询和转换 ​

bash
jq . <data.json>                              # 格式化并验证 JSON
jq -r '.items[].metadata.name' <data.json>    # 原始字符串输出
jq '.items[] | select(.status == "failed")' <data.json>
jq -r '.items[] | [.name, .status] | @tsv' <data.json>
jq -s 'add' <part-*.json>                     # 将多个 JSON 输入收集后相加

处理可能缺失的字段:

bash
jq -r '.items[] | [.name, (.owner // "unknown")] | @tsv' <data.json>

使用 --arg 安全传入变量,避免手工拼 JSON:

bash
jq --arg name "$name" '.items[] | select(.name == $name)' <data.json>

五、日志调查 ​

5.1 文件日志 ​

bash
tail -F <log-file>
grep -nE 'ERROR|FATAL|panic' <log-file>
grep -B 3 -A 8 '<request-id>' <log-file>
zgrep -n '<pattern>' <log-file.gz>

跨轮转文件搜索并保留文件名:

bash
zgrep -Hn '<request-id>' <log-directory>/<prefix>*.gz
grep -Hn '<request-id>' <log-directory>/<prefix>*.log

5.2 时间范围与时区 ​

先确认日志使用 UTC、系统本地时间还是应用自定义时区:

bash
date --iso-8601=seconds
date -u --iso-8601=seconds
timedatectl

日志时间若是可按字典排序的 ISO 8601,可用 awk 粗筛;复杂格式优先使用日志平台或针对格式的解析器,不要用不可靠的字符串比较替代时间解析。

5.3 敏感信息 ​

采集日志前删除或掩码:认证头、Cookie、Token、密码、私钥、身份证件、银行卡号和完整请求体。共享最小必要片段,并保留时间、实例、请求 ID 等关联字段。

六、systemd 与 journald 深度排查 ​

bash
systemctl status <service> --no-pager -l
systemctl show <service> -p ActiveState -p SubState -p ExecMainStatus
systemctl cat <service>                    # Unit 与覆盖配置
systemctl list-dependencies <service>
systemctl list-units --failed

6.1 查询 journal ​

bash
journalctl -u <service> -n 200 --no-pager
journalctl -u <service> --since '30 minutes ago'
journalctl -u <service> --since '2026-08-12 10:00:00' --until '2026-08-12 10:30:00'
journalctl -u <service> -f
journalctl -p err --since today       # err 以及更高优先级
journalctl -b                         # 本次启动
journalctl -b -1                      # 上一次启动(若 journal 持久化)
journalctl --disk-usage

结构化输出:

bash
journalctl -u <service> -o json --since '10 minutes ago' | jq -r '[.__REALTIME_TIMESTAMP, .PRIORITY, .MESSAGE] | @tsv'

6.2 验证 Unit 文件 ​

bash
systemd-analyze verify /etc/systemd/system/<service>.service
systemd-analyze critical-chain

安全修改服务:

bash
sudo systemctl edit <service>   # 创建 drop-in,避免直接改供应商 Unit
sudo systemctl daemon-reload
sudo systemctl restart <service>
systemctl status <service> --no-pager

reset-failed 只清除失败状态和计数,不会修复根因:

bash
sudo systemctl reset-failed <service>

七、CPU、内存与负载 ​

7.1 理解 load average ​

bash
uptime
cat /proc/loadavg
nproc

Load average 包括可运行和不可中断睡眠任务,不等同于 CPU 使用率。需要结合 CPU 核数、vmstat、I/O 和进程状态判断。

7.2 CPU ​

bash
top
ps -eo pid,ppid,user,stat,%cpu,%mem,etime,cmd --sort=-%cpu | head -n 20
pidstat -u 1 10                # sysstat 包
mpstat -P ALL 1 10            # 各 CPU 使用率

%CPU 高可能是正常业务负载;进一步关联请求量、延迟、错误率、线程数和发布变更。

7.3 内存 ​

bash
free -h
vmstat 1 10
ps -eo pid,user,%mem,rss,vsz,cmd --sort=-rss | head -n 20
cat /proc/meminfo

Linux 会使用空闲内存作缓存,不能仅看 free 列。重点关注 available、swap 活动、持续增长的 RSS 和 OOM 证据:

bash
journalctl -k --since today | grep -iE 'out of memory|oom|killed process'

7.4 进程树、线程和打开文件 ​

bash
pstree -ap <pid>
ps -T -p <pid>
ls -l /proc/<pid>/fd | head
cat /proc/<pid>/limits
sudo lsof -p <pid> | head

只有得到授权并理解开销时才在生产使用 strace:

bash
sudo strace -f -tt -T -p <pid>

strace 可能显著增加高频系统调用进程的开销,并暴露敏感参数。限定时间,保存前脱敏:

bash
sudo timeout 15s strace -f -tt -T -p <pid>

八、磁盘与 I/O 排查 ​

8.1 容量、inode 和热点目录 ​

bash
df -hT
df -ih
du -xhd1 <mountpoint> | sort -h
find <mountpoint> -xdev -type f -size +1G -printf '%s %p\n' | sort -nr | head

-xdev 防止越过其他挂载点。无权限目录会导致 du 少算,应记录错误而不是忽略差异。

8.2 已删除但仍占空间的文件 ​

bash
sudo lsof +L1

发现大文件被标记 (deleted) 时,应先判断所属进程能否平滑重载或重启。不要直接改写 /proc/<pid>/fd/*;那可能破坏进程状态。

8.3 I/O 延迟和设备状态 ​

bash
iostat -xz 1 10             # sysstat 包
vmstat 1 10
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS
findmnt
journalctl -k --since today | grep -iE 'I/O error|reset|timeout|filesystem'

iostat 的单一阈值不能跨设备套用。关注延迟、队列、吞吐和业务 SLA 的共同变化,并对比设备的正常基线。

继续阅读