ps -eo state,pid,ppid | grep -E "^Z" 不适合直接对接 Prometheus,因其输出无结构、空格不固定、grep "^Z" 易漏匹配,且非 OpenMetrics 格式,缺少 HELP、TYPE、时间戳等必要元数据。

这个命令本身不能直接对接 Prometheus,因为 ps -eo state,pid,ppid | grep -E "^Z" 只能输出状态为 Z 的进程行(注意:实际中 state 列输出的是单字母状态码,但 ^Z 匹配失败概率高——Z 通常不独占整行开头,前面有空格或制表符),且无结构化格式,Prometheus 无法直接采集。
为什么这条命令不适合直接对接 Prometheus
— ps -eo state,pid,ppid 输出无标题、无对齐保证,字段间空格不固定,grep "^Z" 极易漏匹配(如实际输出可能是 "Z " 或 " Z ")
— 输出是纯文本,不是 Prometheus 要求的 name{label=value} value 格式指标
— 没有时间戳、无类型声明、无 HELP 注释,不符合 OpenMetrics 规范
— Prometheus 只拉取 HTTP 接口(/metrics),不支持执行 shell 命令
正确做法:用 exporter 将僵尸进程转为标准指标
推荐使用轻量级自定义 exporter(如 Python + Flask 或 Go 编写),或复用成熟方案:
-
用 node_exporter 的
processes子系统(需启用):新版 node_exporter(v1.5+)默认开启--collector.processes,它暴露processes_total{state="zombie"}指标,无需额外脚本 -
写一个简单 Bash + Web 服务 exporter:用
python3 -m http.server搭配临时脚本生成指标,例如:#!/bin/bash<br>echo "# HELP zombie_processes_total Number of zombie processes"<br>echo "# TYPE zombie_processes_total gauge"<br>zombie_count=$(ps -eo stat= | grep -c "Z")<br>echo "zombie_processes_total $zombie_count"
保存为/var/lib/zombie-exporter/metrics,再用nohup python3 -m http.server 9200 --directory /var/lib/zombie-exporter &启动 -
用 textfile collector(最稳妥):让 cron 每分钟运行一次脚本,把结果写入
/var/lib/node_exporter/textfile_collector/zombies.prom:#!/bin/bash<br>zcnt=$(ps -eo stat= 2>/dev/null | grep -c "Z" || echo 0)<br>echo "zombie_processes_total $zcnt" > /var/lib/node_exporter/textfile_collector/zombies.prom
确保 node_exporter 启动时加了--collector.textfile.directory=/var/lib/node_exporter/textfile_collector
Prometheus 配置采集
在 prometheus.yml 中添加 job(以 textfile 方式为例):
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- job_name: 'zombie-monitor' static_configs: - targets: ['localhost:9100'] # node_exporter 地址
然后在 Prometheus 表达式浏览器中查:zombie_processes_total —— 当前僵尸数rate(zombie_processes_total[1h]) > 0 —— 近一小时持续存在僵尸
告警与定位增强
光知道数量不够,还需关联父进程信息。可在同一脚本中补充:
- 用
ps -eo pid,ppid,stat,comm | awk '$3 ~ /Z/ {print $2}' | sort | uniq -c统计各父进程产生的僵尸数,写入 label:zombie_by_ppid_total{ppid="8888"} 5 - 结合
ps -o comm= -p $PPID 2>/dev/null获取父进程名,生成:zombie_parent_process{ppid="8888",comm="nginx"} 5 - 在 Grafana 中用
topk(5, zombie_by_ppid_total)快速定位问题父进程

















