进程守护脚本(自动重启)
监控关键进程运行状态,进程异常退出时自动重启,支持重启次数统计和告警通知
详细内容
#!/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": ""}]