僵尸进程已经结束执行,只保留退出状态等待父进程回收。少量短暂僵尸不一定有害,但持续累积会占用 PID,并最终导致 fork: Resource temporarily unavailable。
找出僵尸及其父进程
ps -eo stat,pid,ppid,etimes,comm | awk '$1 ~ /^Z/'
pstree -ap $PPID
cat /proc/$PPID/status | grep -E 'Name|Threads|Sig'
僵尸本身无法被 kill -9 清除。应修复或重启没有调用 wait() 的父进程;父进程退出后,子进程会被 init 或 subreaper 接管并回收。
排查 fork 失败
ulimit -u
cat /proc/sys/kernel/pid_max
ps -eLf | wc -l
systemctl show "$SERVICE" -p TasksCurrent -p TasksMax
除了 PID 用尽,还要检查用户进程限制、systemd TasksMax、容器 PID cgroup 以及内存不足。线程也会计入任务数量。
处理边界
- 先确认父进程和业务影响,再安排滚动重启
- 不通过循环发送信号制造更大进程风暴
- 容器入口进程应具备信号转发和子进程回收能力
- 为 worker 数量、PID 使用率和僵尸数量建立监控
收尾清单
修复后验证僵尸数量不再增长,并通过异常退出、超时和重载场景测试父进程的回收逻辑。