Shell脚本如何监控进程数量

wen 实用脚本 2

Shell脚本如何监控进程数量(实战指南)

目录导读

  1. 为什么需要监控进程数量?
  2. 核心监控原理与常用命令
  3. 实战:编写进程数量监控脚本
  4. 进阶:告警通知与日志记录
  5. 问答专区

为什么需要监控进程数量?

在生产服务器或开发环境中,进程数量异常往往是系统问题的“晴雨表”,举个真实案例:某电商网站业务高峰期,由于PHP-FPM子进程不断膨胀,导致服务器内存耗尽,最终引发502错误,通过进程数量监控脚本,运维人员可以在进程数超过阈值时自动触发告警,从而避免服务宕机。

Shell脚本如何监控进程数量

典型场景包括:

  • 防止僵尸进程堆积导致系统资源耗尽
  • 监控Web服务器(如Nginx、Apache)的worker进程数量,确保负载均衡正常
  • 检测恶意进程或脚本的异常行为
  • 为Docker容器或微服务提供进程健康检查

核心监控原理与常用命令

1 关键命令解析

# 最核心三剑客
ps -ef | grep "进程名" | grep -v grep | wc -l
pgrep -c "进程名"          # 更精确的统计方式
top -bn1 | grep "Tasks"   # 查看系统总进程数

ps命令的陷阱:直接使用ps aux | grep xxx会包含grep自身进程,务必加| grep -v grep过滤。

2 常用指标阈值

监控对象 常见告警阈值 说明
总进程数 > 1000(视硬件配置) 系统可创建进程数上限
单个服务进程 如PHP-FPM > 500 根据worker池配置设定
僵尸进程 > 0 应始终保持为0
子进程增长速率 每分钟增长>20% 可能有内存泄漏

实战:编写进程数量监控脚本

1 基础脚本框架

#!/bin/bash
# 功能:监控指定进程数量,超阈值则告警
PROCESS_NAME="nginx"       # 替换为实际进程名(支持正则)
PROCESS_THRESHOLD=200      # 进程数阈值
SCRIPT_NAME="进程监控脚本"
# 获取进程数量
process_count=$(pgrep -c "$PROCESS_NAME" 2>/dev/null || echo 0)
# 判断是否超限
if [ "$process_count" -gt "$PROCESS_THRESHOLD" ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 警告:$PROCESS_NAME 当前进程数 $process_count,超过阈值 $PROCESS_THRESHOLD"
    # 此处可插入告警动作(见第四部分)
else
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $PROCESS_NAME 进程数正常:$process_count"
fi

2 增强版:多进程监控

#!/bin/bash
declare -A PROC_MAP
PROC_MAP["nginx"]=200
PROC_MAP["php-fpm"]=300
PROC_MAP["mysqld"]=50
for proc in "${!PROC_MAP[@]}"; do
    threshold=${PROC_MAP[$proc]}
    count=$(pgrep -c "$proc")
    echo "$proc 当前进程数: $count / 阈值: $threshold"
done

3 定时执行(crontab)

# 每5分钟执行一次
*/5 * * * * /usr/local/bin/process_monitor.sh >> /var/log/process_monitor.log 2>&1

进阶:告警通知与日志记录

1 集成企业微信/Slack通知

# 企业微信机器人通知函数
send_wechat_notification() {
    local message=$1
    local webhook_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY"
    curl -X POST -H "Content-Type: application/json" \
         -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$message\"}}" \
         "$webhook_url"
}
# 在告警逻辑中调用
if [ "$process_count" -gt "$PROCESS_THRESHOLD" ]; then
    send_wechat_notification "服务器进程告警:$PROCESS_NAME 当前数量 $process_count"
fi

2 健康日志自动轮转

log_file="/var/log/process_monitor.log"
[ ! -f "$log_file" ] && touch "$log_file"
# 日志大小限制(10MB自动切割)
if [ $(stat -c%s "$log_file") -gt 10485760 ]; then
    mv "$log_file" "${log_file}.$(date +%Y%m%d%H%M%S)"
    touch "$log_file"
fi

问答专区

Q1:为什么我的ps命令统计结果比预期多1个进程? A:经典陷阱!ps aux | grep nginx会包含当前grep命令自身的进程行,解决方案:使用grep -v grep过滤,或者直接用pgrep -c nginx更准确。

Q2:监控脚本在容器内执行需要注意什么? A:容器内进程空间隔离,ps命令可能无法看到宿主机进程,建议:

  • 在宿主机层面部署监控脚本
  • 容器内使用/proc文件系统直接读取/proc/1/status判断init进程健康状态
  • 对于Docker,可设置--restart=always策略

Q3:如何监控所有进程的总数?

total_procs=$(ps -e --no-headers | wc -l)
# 或使用/proc更高效
total_procs=$(ls -d /proc/[0-9]* 2>/dev/null | wc -l)

Q4:脚本执行后没有任何输出,可能是什么问题?

  1. 检查脚本是否有执行权限:chmod +x script.sh
  2. 测试pgrep命令本身是否能正确匹配进程名
  3. 确认crontab环境变量(PATH问题需使用绝对路径)
  4. 查看日志文件是否有写入权限

Q5:是否有更专业的进程监控工具? A:对于复杂监控场景,可组合工具:

  • Prometheus + node_exporter(集成进程数指标)
  • Monit(轻量级进程监控,支持自动恢复)
  • Sysdig(Capture进程行为) 但Shell脚本的优势在于:零依赖、底层可见性强、适合快速部署验证。

后记:进程监控脚本是运维工具箱里的“瑞士军刀”,它不需要复杂的架构,却能解决核心的异常检测问题,建议运维人员将本文的脚本实践为模板,根据自身业务特性(如微服务进程名、容器编排)进行个性化定制,真正实现“故障未至,监控先行”。(文末附赠“三招测试小技巧”:1. 手动kill子进程测试阈值触发;2. 插入假进程测试正则匹配;3. 拔网线测试告警渠道可用性。)

抱歉,评论功能暂时关闭!