进程守护脚本(自动重启)

代码脚本 · 基础巡检

监控关键进程运行状态,进程异常退出时自动重启,支持重启次数统计和告警通知

详细内容

#!/bin/bash # ========================================== # 进程守护脚本 # 用途:监控关键进程,异常退出自动重启 # 使用方法: # 1. 修改 PROCESS_LIST 配置 # 2. bash process_guardian.sh # 3. 建议用systemd或nohup后台运行 # ========================================== # ========== 配置 ========== # 进程列表:进程名|启动命令|最大重启次数(0表示无限) PROCESS_LIST=( "nginx|systemctl start nginx|5" "mysql|systemctl start mysql|5" "redis|systemctl start redis|3" # "myapp|/opt/myapp/start.sh|0" ) CHECK_INTERVAL=10 # 检测间隔(秒) MAX_RESTART_WINDOW=300 # 重启统计窗口(秒),超过此时间重置计数 LOG_FILE="/var/log/process_guardian.log" ALERT_EMAIL="" # 告警邮箱 WECOM_WEBHOOK="" # 企业微信Webhook # ========================== mkdir -p "$(dirname "$LOG_FILE")" declare -A RESTART_COUNT declare -A LAST_RESTART_TIME log_msg() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } send_alert() { local title="$1" local content="$2" log_msg "【告警】$title: $content" if [ -n "$ALERT_EMAIL" ]; then echo -e "$content" | mail -s "【进程告警】$title" "$ALERT_EMAIL" 2>/dev/null fi if [ -n "$WECOM_WEBHOOK" ]; then curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{ "msgtype": "text", "text": {"content": "【进程告警】$title\n$content\n主机: $(hostname)"} }" >/dev/null 2>&1 fi } check_process() { local proc_name="$1" local start_cmd="$2" local max_restart="$3" # 检查进程是否运行 if pgrep -x "$proc_name" >/dev/null 2>&1 || systemctl is-active --quiet "$proc_name" 2>/dev/null; then return 0 fi # 进程未运行,尝试重启 log_msg "进程 $proc_name 未运行,尝试重启..." # 检查重启计数窗口 local now=$(date +%s) local last_time=${LAST_RESTART_TIME[$proc_name]:-0} if [ $((now - last_time)) -gt $MAX_RESTART_WINDOW ]; then RESTART_COUNT[$proc_name]=0 fi # 检查是否超过最大重启次数 local count=${RESTART_COUNT[$proc_name]:-0} if [ "$max_restart" -gt 0 ] && [ "$count" -ge "$max_restart" ]; then send_alert "进程 $proc_name 重启次数超限" "已重启 $count 次,超过最大限制 $max_restart 次,请人工检查!" return 1 fi # 执行重启 if eval "$start_cmd" >> "$LOG_FILE" 2>&1; then sleep 3 if pgrep -x "$proc_name" >/dev/null 2>&1 || systemctl is-active --quiet "$proc_name" 2>/dev/null; then RESTART_COUNT[$proc_name]=$((count + 1)) LAST_RESTART_TIME[$proc_name]=$now log_msg "✓ 进程 $proc_name 重启成功 (第${RESTART_COUNT[$proc_name]}次)" send_alert "进程 $proc_name 已自动重启" "进程异常退出,已自动重启成功 (第${RESTART_COUNT[$proc_name]}次)" else log_msg "✗ 进程 $proc_name 重启后仍未运行" send_alert "进程 $proc_name 重启失败" "执行重启命令后进程仍未运行,请人工检查!" fi else log_msg "✗ 进程 $proc_name 重启命令执行失败" send_alert "进程 $proc_name 重启命令失败" "重启命令执行出错,请检查命令是否正确" fi } log_msg "===== 进程守护启动 =====" log_msg "监控进程数: ${#PROCESS_LIST[@]}" log_msg "检测间隔: ${CHECK_INTERVAL}秒" # 初始化重启计数 for item in "${PROCESS_LIST[@]}"; do proc_name=$(echo "$item" | cut -d'|' -f1) RESTART_COUNT[$proc_name]=0 LAST_RESTART_TIME[$proc_name]=0 log_msg " - 监控: $proc_name" done # 主循环 while true; do for item in "${PROCESS_LIST[@]}"; do proc_name=$(echo "$item" | cut -d'|' -f1) start_cmd=$(echo "$item" | cut -d'|' -f2) max_restart=$(echo "$item" | cut -d'|' -f3) check_process "$proc_name" "$start_cmd" "$max_restart" done sleep "$CHECK_INTERVAL" done

适配环境

适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+

依赖环境:bash 4.0+

参数说明

[{"name": "PROCESS_LIST", "label": "\u8fdb\u7a0b\u5217\u8868(\u6bcf\u884c\u4e00\u4e2a\uff0c\u683c\u5f0f\uff1a\u8fdb\u7a0b\u540d|\u542f\u52a8\u547d\u4ee4|\u6700\u5927\u91cd\u542f\u6b21\u6570)", "type": "textarea", "default": "nginx|systemctl start nginx|5"}, {"name": "CHECK_INTERVAL", "label": "\u68c0\u6d4b\u95f4\u9694(\u79d2)", "default": "10"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}]
进程守护监控自动重启高可用

更多基础巡检