4.3.6 进程异常排查流程与案例

进程异常排查流程与案例#

一、排查流程与原理草图#

文章图片

二、环境准备与工具安装#

以下以 Debian/Ubuntu 与 CentOS/RHEL 为例

1) 安装基础诊断工具

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y sysstat strace lsof psmisc smem linux-tools-common linux-tools-generic

# CentOS/RHEL
sudo yum install -y sysstat strace lsof psmisc smem perf

2) 启用 sysstat 采集(sar 依赖)

# Debian/Ubuntu
sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
sudo systemctl enable --now sysstat

# CentOS/RHEL
sudo systemctl enable --now sysstat

3) 命令解释速览
- ps -ef | grep <svc>:查看进程存在与 PID
- top -H -p <pid>:查看进程内线程 CPU
- pidstat -p <pid> 1:周期输出进程 CPU/内存/IO
- vmstat 1:系统级 CPU、内存、上下文
- iostat -xz 1:磁盘 IO 延迟与饱和度
- strace -p <pid>:系统调用阻塞点
- pmap -x <pid>:内存映射与堆增长
- lsof -p <pid>:打开文件/连接
- ss -antp | grep <pid>:连接状态与队列

三、标准排查流程(含完整示例)#

示例目标:定位服务 demo-api 响应慢问题

步骤1:确认现象与范围

# 查看告警时间、确认服务是否抖动
date
systemctl status demo-api
journalctl -u demo-api --since "10 min ago" | tail -n 50

预期效果:确认服务未崩溃但响应慢,日志出现超时。

步骤2:定位异常进程

# 获取 PID
ps -ef | grep demo-api | grep -v grep

# 实时线程 CPU
top -H -p <pid>

# 持续观测 1 秒间隔
pidstat -p <pid> 1

解释
- top -H 显示每个线程 CPU,便于定位热线程
- pidstat 输出 %CPUVSZRSScswch/s

步骤3:系统资源评估

vmstat 1 5
iostat -xz 1 5
sar -q 1 5

解释
- vmstatsi/so 表示换入/换出,非 0 说明内存压力
- iostatawait 高说明 IO 延迟
- sar -qrunq-sz 高说明就绪队列堆积

步骤4:进程级诊断

# 观察阻塞系统调用
strace -p <pid> -tt -T -f -o /tmp/strace.demo-api.log

# 观察内存映射
pmap -x <pid> | tail -n 20

# 查看打开文件与连接
lsof -p <pid> | head -n 20
ss -antp | grep <pid> | head -n 10

解释
- -tt -T 显示时间戳与调用耗时
- -f 追踪线程/子进程

步骤5:依赖链路确认

# 连接状态
ss -antp | grep <pid> | awk '{print $1,$2,$3,$4,$5,$6}'

# 检查下游是否超时(示例:mysql)
mysqladmin -uroot -p ping

预期效果:判断是否下游连接 SYN-SENT/ESTABLISHED 堆积。

步骤6:处置与复盘

# 临时止血:重启服务(示例)
sudo systemctl restart demo-api

# 记录诊断信息
tar czf /tmp/demo-api-trace.tgz /tmp/strace.demo-api.log /var/log/demo-api/*

四、典型案例 1:CPU 飙高导致服务响应慢#

现象:请求超时、load 短期飙升
排查过程

top -H -p <pid>
perf top -p <pid>

解释perf top 定位热点函数
原因:异常输入触发高复杂度正则
处理

# 伪代码修复思路:增加超时与输入长度限制
# 规则示例
MAX_LEN=2048
if len(input) > MAX_LEN: reject

五、典型案例 2:内存持续增长导致 OOM#

现象:服务重启,dmesg 出现 OOM
排查过程

dmesg -T | grep -i "oom"
pmap -x <pid> | tail -n 20
smem -p | head -n 10

原因:缓存无限增长
处理示例(配置片段)

# /etc/demo-api/conf.d/cache.conf
cache.max_size_mb=512
cache.eviction_policy=LRU

六、典型案例 3:I/O 阻塞引发性能抖动#

现象:TPS 波动、响应抖动
排查过程

iostat -xz 1
strace -p <pid> -tt -T | grep fsync

原因:频繁 fsync
处理示例

# /etc/demo-api/conf.d/logging.conf
log.flush=interval
log.flush_interval_ms=500

七、典型案例 4:进程卡死无响应#

现象:进程存在但无法响应
排查过程

strace -p <pid> -tt -T
pstack <pid> | head -n 50

原因:锁竞争/死锁
处理:降低锁粒度,增加超时与死锁检测

八、排错清单(SOP 片段)#

# 1. 进程是否存在
ps -ef | grep demo-api | grep -v grep

# 2. 线程 CPU 是否异常
top -H -p <pid>

# 3. 系统是否资源耗尽
vmstat 1 5
iostat -xz 1 5

# 4. 进程是否阻塞系统调用
strace -p <pid> -tt -T -f -o /tmp/strace.log

# 5. 连接是否堆积
ss -antp | grep <pid> | head

九、练习题(含参考步骤)#

练习1:模拟 CPU 飙高并定位热点

# 1) 启动 CPU 压力进程
sudo apt-get install -y stress
stress --cpu 1 --timeout 30

# 2) 用 top 和 pidstat 观察
top
pidstat 1

# 3) 记录现象并写出诊断结论

练习2:模拟 IO 延迟

# 1) 制造磁盘写入
dd if=/dev/zero of=/tmp/bigfile bs=1M count=2048 oflag=direct

# 2) 观察 iostat await
iostat -xz 1

十、最佳实践#

  • 关键进程建立基线:CPU、RSS、FD、线程数、QPS
  • 统一诊断脚本与输出格式,方便归档与复盘
  • 报警与日志统一时间戳与机器标识
  • 预案演练:每季度至少一次应急排查演练