本文目录导读:

我来帮你写一个自动重启服务的脚本,提供几种不同的实现方案:
基础版 - 检查并重启服务 (Bash)
#!/bin/bash
# 服务名称
SERVICE_NAME="your-service-name"
# 检查服务是否运行
if ! systemctl is-active --quiet $SERVICE_NAME; then
echo "$(date): $SERVICE_NAME 未运行,正在重启..."
systemctl restart $SERVICE_NAME
# 验证重启结果
if systemctl is-active --quiet $SERVICE_NAME; then
echo "$(date): $SERVICE_NAME 重启成功"
else
echo "$(date): $SERVICE_NAME 重启失败"
fi
fi
带重试机制的版本
#!/bin/bash
SERVICE_NAME="your-service-name"
MAX_RETRIES=3
RETRY_INTERVAL=10 # 秒数
restart_service() {
local retry_count=0
while [ $retry_count -lt $MAX_RETRIES ]; do
echo "$(date): 尝试重启 $SERVICE_NAME (第 $((retry_count+1)) 次)"
systemctl restart $SERVICE_NAME
# 等待服务启动
sleep 5
if systemctl is-active --quiet $SERVICE_NAME; then
echo "$(date): $SERVICE_NAME 重启成功"
return 0
fi
((retry_count++))
sleep $RETRY_INTERVAL
done
echo "$(date): $SERVICE_NAME 重启失败,已达最大重试次数"
send_alert "服务重启失败: $SERVICE_NAME"
return 1
}
# 检查并重启
if ! systemctl is-active --quiet $SERVICE_NAME; then
restart_service
fi
监控进程并自动重启
#!/bin/bash
# 监控的进程名或命令
PROCESS_NAME="your-process-name"
PROCESS_CMD="/path/to/your/command"
LOG_FILE="/var/log/process_monitor.log"
restart_process() {
echo "$(date): 启动进程 $PROCESS_NAME" >> $LOG_FILE
# 杀死旧进程(如果存在)
pkill -f $PROCESS_NAME 2>/dev/null
# 后台启动进程
nohup $PROCESS_CMD > /dev/null 2>&1 &
# 等待进程启动
sleep 2
# 检查进程是否启动
if pgrep -f $PROCESS_NAME > /dev/null; then
echo "$(date): 进程 $PROCESS_NAME 启动成功" >> $LOG_FILE
return 0
else
echo "$(date): 进程 $PROCESS_NAME 启动失败" >> $LOG_FILE
return 1
fi
}
# 主循环
while true; do
if ! pgrep -f $PROCESS_NAME > /dev/null; then
echo "$(date): 进程 $PROCESS_NAME 不存在,正在重启..." >> $LOG_FILE
restart_process
if [ $? -ne 0 ]; then
echo "$(date): 重启失败,等待 30 秒后重试" >> $LOG_FILE
sleep 30
continue
fi
fi
sleep 10
done
使用 cron 定时检查
#!/bin/bash
# 保存为 /usr/local/bin/service_monitor.sh
# 然后添加到 crontab: */5 * * * * /usr/local/bin/service_monitor.sh
SERVICE_NAME="your-service"
MAX_MEMORY=500 # MB,可选:内存限制
MAX_CPU=90 # 百分比,可选:CPU限制
restart_service() {
echo "$(date): 开始重启服务 $SERVICE_NAME"
systemctl restart $SERVICE_NAME
echo "$(date): 服务 $SERVICE_NAME 已重启"
logger "服务 $SERVICE_NAME 已自动重启"
}
# 1. 检查服务是否运行
if ! systemctl is-active --quiet $SERVICE_NAME; then
restart_service
exit 0
fi
# 2. 检查资源使用(可选)
PID=$(pgrep -f $SERVICE_NAME | head -1)
if [ ! -z "$PID" ]; then
# 检查内存
MEMORY=$(ps -o rss= -p $PID | awk '{print $1/1024}')
if [ $(echo "$MEMORY > $MAX_MEMORY" | bc) -eq 1 ]; then
echo "$(date): 内存使用超过限制 ($MEMORY MB)"
restart_service
exit 0
fi
# 检查CPU
CPU=$(ps -o %cpu= -p $PID)
if [ $(echo "$CPU > $MAX_CPU" | bc) -eq 1 ]; then
echo "$(date): CPU使用超过限制 ($CPU%)"
restart_service
exit 0
fi
fi
增强版 - 带日志和告警
#!/bin/bash
# 配置
SERVICE_NAME="your-service"
LOG_DIR="/var/log/service_auto_restart"
LOG_FILE="$LOG_DIR/restart.log"
ALERT_EMAIL="admin@example.com"
MAX_RESTARTS=5 # 每小时最大重启次数
RESTART_COUNT_FILE="/tmp/restart_count"
# 创建日志目录
mkdir -p $LOG_DIR
# 记录日志
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> $LOG_FILE
}
# 发送告警
send_alert() {
local message="$1"
echo "$message" | mail -s "服务重启告警: $SERVICE_NAME" $ALERT_EMAIL
log "发送告警: $message"
}
# 检查重启频率
check_restart_rate() {
local current_hour=$(date +%H)
local current_count=0
# 读取当前小时的重启次数
if [ -f "$RESTART_COUNT_FILE" ]; then
local saved_hour=$(cat $RESTART_COUNT_FILE | head -1)
if [ "$saved_hour" == "$current_hour" ]; then
current_count=$(cat $RESTART_COUNT_FILE | tail -1)
else
# 新的一小时,重置计数
current_count=0
fi
fi
if [ $current_count -ge $MAX_RESTARTS ]; then
log "达到每小时最大重启次数 ($MAX_RESTARTS)"
return 1
fi
# 更新计数
echo "$current_hour" > $RESTART_COUNT_FILE
echo $((current_count + 1)) >> $RESTART_COUNT_FILE
return 0
}
# 重启服务
restart_service() {
log "开始重启服务 $SERVICE_NAME"
# 记录重启原因
if [ ! -z "$1" ]; then
log "重启原因: $1"
fi
# 执行重启
systemctl restart $SERVICE_NAME
local restart_status=$?
sleep 5
# 验证
if systemctl is-active --quiet $SERVICE_NAME; then
log "服务重启成功"
# 检查重启频率
if ! check_restart_rate; then
send_alert "服务频繁重启,请检查: $SERVICE_NAME"
fi
return 0
else
log "服务重启失败"
send_alert "服务重启失败: $SERVICE_NAME"
return 1
fi
}
# 主逻辑
main() {
# 检查服务状态
if ! systemctl is-active --quiet $SERVICE_NAME; then
restart_service "服务未运行"
exit $?
fi
# 检查是否僵死
if systemctl status $SERVICE_NAME | grep -q "Active: activating"; then
restart_service "服务卡在激活状态"
exit $?
fi
log "服务运行正常"
}
main
使用 systemd 定时器(推荐方案)
创建 Timer 配置文件 /etc/systemd/system/service_monitor.timer:
[Unit] Description=Service Monitor Timer Requires=service_monitor.service [Timer] OnCalendar=*:0/5 Persistent=true [Install] WantedBy=timers.target
创建服务文件 /etc/systemd/system/service_monitor.service:
[Unit] Description=Service Monitor After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/service_monitor.sh StandardOutput=journal
启用定时器:
sudo systemctl enable service_monitor.timer sudo systemctl start service_monitor.timer
使用方法
- 修改配置:将
your-service-name替换为实际的服务名 - 添加执行权限:
chmod +x script.sh
- 设置定时任务:
crontab -e # 添加每分钟检查 * * * * * /path/to/script.sh
选择适合你场景的方案,建议先测试再部署到生产环境。