15 10 月 2026

top 一看 CPU 100%、load 飙到几十,但找不到元凶——僵尸进程、失控子进程、异常线程这三类最阴间。这篇讲它们的特征、定位方法和处置流程,命令全部可抄。

需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署,进程异常面板直接看。

一、先分清三类异常进程

类型top 里的状态特征危险性
僵尸进程Z (zombie)已退出但父进程没回收一般不占 CPU,但 PID 耗尽会出大事
失控进程R/D,CPU 或 load 高跑飞的计算/挖矿/死循环直接拖垮机器
D 状态进程D (uninterruptible sleep)卡在磁盘 IO,杀不掉等 IO 或重启,通常是磁盘/网络存储问题
# 一眼看全貌
top -bn1 | head -20
uptime          # load average: 1分钟 5分钟 15分钟

# load 的解读:双核机器 load 2 是满负荷,load 20 就是严重过载
nproc           # 看几核

二、僵尸进程:找到不撒手的父进程

僵尸进程是「死了没人埋」:子进程退出了,父进程没调用 wait() 回收,于是留下一个空壳占着 PID。

# 找僵尸进程
ps aux | awk '$8 ~ /Z/ {print}'

# 或
ps -eo pid,ppid,stat,comm | grep -w Z

# 看它的父进程是谁
ps -o pid,ppid,comm -p <僵尸PID>

处置逻辑:僵尸本身没资源可回收,杀僵尸没用,要处理它爹:

# 1. 父进程自己异常(比如卡死不回收)
kill -TERM <父PID>        # 先温柔地
sleep 5
kill -9 <父PID>           # 再暴力地

# 2. 父进程是 init/systemd(被领养后还被僵尸?少见)
#    基本只能重启机器

# 3. 父进程是游戏服/业务程序
#    说明程序有 bug:子进程退出没回收。看服务端日志有没有报错
#    长期方案:换版本、加进程守护、或定时重启服务

批量清理脚本(慎用,会重启父进程):

#!/bin/bash
# 找出僵尸进程的父进程(排除 init),重启它们
for zpid in $(ps -eo pid,stat --no-headers | awk '$2 ~ /Z/ {print $1}'); do
  ppid=$(ps -o ppid= -p $zpid 2>/dev/null | tr -d ' ')
  if [ -n "$ppid" ] && [ "$ppid" -gt 1 ]; then
    pname=$(ps -o comm= -p $ppid 2>/dev/null)
    echo "僵尸 $zpid 的父进程: $ppid ($pname)"
    # 确认是业务进程再取消下面注释:
    # systemctl restart "$pname" 2>/dev/null || kill -TERM "$ppid"
  fi
done

三、失控进程:谁在吃 CPU

# 按 CPU 排序,前十里找元凶
ps aux --sort=-%cpu | head -10

# 看线程级(某个线程跑飞)
top -H -p <PID>

# 看进程完整路径和启动参数(判断是不是你起的)
ls -l /proc/<PID>/exe
cat /proc/<PID>/cmdline | tr '\0' ' '; echo

可疑进程黑名单(名字像但不是你的):

特征判断
xmrig、minerd、kdevtmpfsi挖矿木马,立刻杀+查入侵
名字随机乱码、跑在 /tmp、/dev/shm高度可疑
kworker 占 100% CPU内核线程异常,查 dmesg
你完全不认识的 java/python 常驻可能是被部署的webshell

处置流程:

# 1. 留证据(别直接杀,先看它从哪来)
cat /proc/<PID>/cwd -l 2>/dev/null; ls -l /proc/<PID>/cwd
cat /proc/<PID>/cmdline | tr '\0' ' '

# 2. 杀掉
kill -9 <PID>

# 3. 找根:定时任务、启动项、webshell
crontab -l; ls /etc/cron.d/ /var/spool/cron/crontabs/
systemctl list-unit-files --state=enabled | grep -v known

# 4. 完整入侵排查

确认是被入侵就走服务器被入侵应急排查全流程,别杀完进程就当没事了——后门还在,明天它又回来。

四、D 状态与 load 飙高

load 高但 CPU 空闲、进程一片 D 状态——等磁盘/网络存储:

# 看 D 状态进程
ps -eo pid,stat,comm | awk '$2 ~ /D/'

# 看内核在等什么
cat /proc/<PID>/stack     # 需要 root
dmesg -T | tail -30       # 磁盘报错在这里

常见原因:

原因验证解法
磁盘 IO 打满iostat -xz 1 看 %util升级磁盘/减负载,见磁盘 IO 实战
NFS/网络存储挂了mount 看有没有 hungumount -l 强卸或重启
磁盘硬件故障dmesg 有 I/O error立刻备份数据,开工单换盘
内核死锁 bug全屏 D 状态无进展重启,升级内核

D 状态进程 kill -9 都杀不掉,只能等 IO 返回或重启——所以磁盘故障苗头出现时第一反应是备份,见服务器备份与快照策略。

五、进程数异常:fork 炸弹与 PID 耗尽

# 当前进程数 vs 上限
ps -eL --no-headers | wc -l
cat /proc/sys/kernel/pid_max
ulimit -u              # 当前 shell 的用户进程数限制

进程数几万、PID 快到上限,不是被攻击就是有程序在疯狂 fork:

# 找 fork 大户:同一父进程下挂一堆子进程
ps -eo ppid --no-headers | sort | uniq -c | sort -rn | head -5

# 紧急限制单用户进程数(治标)
# /etc/security/limits.conf 加:
* hard nproc 4096

游戏服场景:服务端崩溃后重启脚本写错,每 30 秒起一个新进程,一天攒几千个。检查你的守护配置是不是「起了不检查旧的」,见systemd 服务与开机自启。

六、日常监控:让异常早发现

# 每日巡检三行
ps aux --sort=-%cpu | head -3      # CPU 前三
ps -eo stat --no-headers | grep -c Z   # 僵尸数
uptime                              # load

做成 cron 每日邮件报告,模板见服务器日常巡检清单与自动化。监控告警体系见Prometheus 监控体系。

排查口诀:先 uptime 看 load,再 top 找 CPU,ps 看状态位,iostat 看磁盘,dmesg 看内核,crontab 查根。按顺序来,没有查不到的问题。


进程异常大多有迹可循:僵尸找爹、跑飞查源、D 状态看盘、进程暴涨防 fork。把这篇的排查顺序记熟,CPU 100% 再也吓不到你。

需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署。延伸阅读:服务器资源排查实战、Linux 性能分析三板斧、自动化运维脚本集锦。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:云服务器磁盘类型与 IO 性能:游戏服卡顿的隐藏瓶颈
  2. 下一篇:CDN 加速配置实战:缓存策略、源站保护、NAT 型适配
发表评论 4

取消回复