定时重启某个服务的脚本

wen 实用脚本 2

本文目录导读:

定时重启某个服务的脚本

  1. 方案1:Systemd Timer(推荐生产环境使用)
  2. 方案2:Bash 脚本 + Crontab
  3. 方案3:带依赖检查的高级脚本
  4. 方案4:Crontab 配置
  5. 设置脚本权限和使用
  6. 简洁版脚本
  7. 使用建议

我来提供一个功能完善的定时重启服务脚本,包含多种实现方式。

方案1:Systemd Timer(推荐生产环境使用)

创建服务定时器

# 1. 创建服务单元文件
sudo nano /etc/systemd/system/my-service.service
[Unit]
Description=My Service
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/python3 /var/www/myapp/app.py
Restart=always
RestartSec=5
# 2. 创建定时器文件
sudo nano /etc/systemd/system/my-service.timer
[Unit]
Description=Restart My Service Timer
[Timer]
# 每天凌晨3点重启
OnCalendar=*-*-* 03:00:00
# 或每4小时重启
# OnCalendar=*:0/4
# 系统启动后延迟10分钟执行
# OnBootSec=10min
Persistent=true
[Install]
WantedBy=timers.target
# 3. 启用定时器
sudo systemctl daemon-reload
sudo systemctl enable --now my-service.timer
sudo systemctl list-timers

方案2:Bash 脚本 + Crontab

通用服务重启脚本

#!/bin/bash
# sync_restart_service.sh
# 功能:定时重启指定服务
# 用法:./restart_service.sh <service_name> [--dry-run]
set -euo pipefail
# ===== 配置 =====
SERVICE_NAME="${1:-}"
DRY_RUN=false
LOG_FILE="/var/log/service_restart.log"
MAX_RETRIES=3
RETRY_INTERVAL=10
# ===== 颜色输出 =====
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ===== 函数 =====
log() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $1" | tee -a "$LOG_FILE"
}
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log "${RED}错误:该脚本需要root权限运行${NC}"
        exit 1
    fi
}
validate_service() {
    if [[ -z "$SERVICE_NAME" ]]; then
        log "${RED}错误:请提供服务名称${NC}"
        echo "用法: $0 <service_name> [--dry-run]"
        exit 1
    fi
    if ! systemctl list-units --type=service --all | grep -q "$SERVICE_NAME"; then
        log "${RED}错误:服务 $SERVICE_NAME 不存在${NC}"
        exit 1
    fi
}
restart_service() {
    if [[ "$DRY_RUN" == true ]]; then
        log "${YELLOW}[DRY RUN] 将重启服务: $SERVICE_NAME${NC}"
        return 0
    fi
    log "开始重启服务: $SERVICE_NAME"
    # 尝试停止服务
    if systemctl stop "$SERVICE_NAME" 2>/dev/null; then
        log "服务已停止"
    else
        log "${YELLOW}警告:服务停止失败,尝试强制停止${NC}"
        systemctl kill -SIGKILL "$SERVICE_NAME" 2>/dev/null || true
        sleep 5
    fi
    # 清理相关进程(可选)
    # pkill -f "$SERVICE_PATTERN" || true
    # 启动服务并重试
    local attempt=1
    while [[ $attempt -le $MAX_RETRIES ]]; do
        if systemctl start "$SERVICE_NAME"; then
            log "${GREEN}服务启动成功${NC}"
            return 0
        else
            log "${YELLOW}启动尝试 $attempt/$MAX_RETRIES 失败,${RETRY_INTERVAL}秒后重试${NC}"
            sleep "$RETRY_INTERVAL"
            attempt=$((attempt + 1))
        fi
    done
    log "${RED}错误:服务启动失败,已重试 $MAX_RETRIES 次${NC}"
    return 1
}
check_service_status() {
    local status
    status=$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || echo "unknown")
    if [[ "$status" == "active" ]]; then
        log "服务当前状态: ${GREEN}运行中${NC}"
    else
        log "服务当前状态: ${RED}$status${NC}"
    fi
    # 显示服务资源占用
    ps aux | grep -E "$SERVICE_NAME" | grep -v grep | head -5 || true
}
main() {
    check_root
    validate_service
    # 解析参数
    for arg in "$@"; do
        case "$arg" in
            --dry-run)
                DRY_RUN=true
                ;;
        esac
    done
    log "========= 服务重启脚本开始 ========="
    # 显示当前服务信息
    check_service_status
    # 执行重启
    if restart_service; then
        log "${GREEN}服务 $SERVICE_NAME 重启成功${NC}"
    else
        log "${RED}服务 $SERVICE_NAME 重启失败,需要人工干预${NC}"
        exit 1
    fi
    # 最终状态检查
    sleep 2
    if systemctl is-active --quiet "$SERVICE_NAME"; then
        log "${GREEN}服务已恢复运行${NC}"
    else
        log "${RED}警告:服务未正常启动${NC}"
        exit 1
    fi
    log "========= 服务重启脚本结束 ========="
}
# ===== 执行 =====
main "$@"

方案3:带依赖检查的高级脚本

#!/bin/bash
# smart_restart_service.sh
# 更智能的服务重启脚本
set -euo pipefail
# ===== 配置 =====
SERVICE_NAME="${1:?错误:请提供服务名称}"
LOG_FILE="/var/log/smart_restart.log"
PRE_CHECK_SCRIPT="/etc/nginx/nginx.conf"  # 可选
POST_CHECK_SCRIPT="/usr/local/bin/check_service.py"  # 可选
# ===== 颜色输出 =====
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# ===== 日志函数 =====
log() {
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# ===== 依赖检查 =====
check_dependencies() {
    log "检查依赖服务..."
    local dependencies=("database" "network.target" "redis")
    for dep in "${dependencies[@]}"; do
        if systemctl is-active --quiet "$dep" 2>/dev/null; then
            log "  ✓ $dep 正常"
        else
            log "${YELLOW}  ⚠ $dep 未运行,请确认是否影响${NC}"
        fi
    done
}
# ===== 优雅重启 =====
graceful_restart() {
    log "执行优雅重启..."
    # 发送SIGTERM信号(优雅终止)
    systemctl kill -s SIGTERM "$SERVICE_NAME"
    # 等待进程退出
    local timeout=30
    local elapsed=0
    while systemctl is-active --quiet "$SERVICE_NAME" && [[ $elapsed -lt $timeout ]]; do
        sleep 1
        elapsed=$((elapsed + 1))
    done
    if systemctl is-active --quiet "$SERVICE_NAME"; then
        log "${YELLOW}优雅退出超时,强制终止${NC}"
        systemctl kill -s SIGKILL "$SERVICE_NAME"
        sleep 2
    fi
}
# ===== 服务启动 =====
start_with_health_check() {
    log "启动服务..."
    systemctl start "$SERVICE_NAME"
    # 健康检查
    local retries=5
    local check_interval=3
    for i in $(seq 1 $retries); do
        sleep "$check_interval"
        if systemctl is-active --quiet "$SERVICE_NAME"; then
            log "${GREEN}服务启动成功${NC}"
            return 0
        fi
        log "等待服务就绪... attempt $i/$retries"
    done
    log "${RED}服务启动失败,健康检查未通过${NC}"
    return 1
}
# ===== 主函数 =====
main() {
    echo "====================="
    log "智能服务重启脚本启动"
    echo "====================="
    # 检查root权限
    if [[ $EUID -ne 0 ]]; then
        log "${RED}错误:需要root权限${NC}"
        exit 1
    fi
    # 检查服务是否存在
    if ! systemctl list-units --type=service --all | grep -q "$SERVICE_NAME"; then
        log "${RED}错误:服务 $SERVICE_NAME 不存在${NC}"
        exit 1
    fi
    # 记录服务信息
    log "服务名称: $SERVICE_NAME"
    log "当前状态: $(systemctl is-active $SERVICE_NAME)"
    # 检查依赖
    check_dependencies
    # 配置预检查
    if [[ -n "$PRE_CHECK_SCRIPT" ]] && [[ -f "$PRE_CHECK_SCRIPT" ]]; then
        log "检查配置语法..."
        if nginx -t 2>/dev/null; then
            log "${GREEN}配置检查通过${NC}"
        else
            log "${RED}配置检查失败,中止重启${NC}"
            exit 1
        fi
    fi
    # 执行重启
    if [[ "$(systemctl is-active $SERVICE_NAME)" == "active" ]]; then
        graceful_restart
        sleep 2
    fi
    # 启动服务
    if start_with_health_check; then
        log "${GREEN}服务重启完成${NC}"
        # 执行后检查
        if [[ -n "$POST_CHECK_SCRIPT" ]] && [[ -x "$POST_CHECK_SCRIPT" ]]; then
            "$POST_CHECK_SCRIPT" "$SERVICE_NAME" || {
                log "${RED}后检查脚本执行失败${NC}"
                exit 1
            }
        fi
    else
        log "${RED}服务重启失败,需要人工干预${NC}"
        exit 1
    fi
    echo "====================="
    log "脚本执行完毕"
    echo "====================="
}
# 执行
main

方案4:Crontab 配置

# 编辑crontab
crontab -e
# 每天凌晨3点重启
0 3 * * * /usr/local/bin/restart_service.sh myservice
# 每6小时重启
0 */6 * * * /usr/local/bin/restart_service.sh myservice
# 每周一凌晨2点重启
0 2 * * 1 /usr/local/bin/restart_service.sh myservice
# 每天重启并记录日志
0 2 * * * /usr/local/bin/restart_service.sh myservice >> /var/log/restart.log 2>&1

设置脚本权限和使用

# 设置执行权限
chmod +x restart_service.sh
# 测试运行(dry-run模式)
sudo ./restart_service.sh myservice --dry-run
# 实际运行
sudo ./restart_service.sh myservice
# 查看日志
cat /var/log/service_restart.log

简洁版脚本

#!/bin/bash
# restart.sh - 简洁版定时重启脚本
SERVICE="${1:?Usage: $0 <service_name>}"
echo "正在重启服务: $SERVICE"
systemctl restart "$SERVICE"
if systemctl is-active --quiet "$SERVICE"; then
    echo "✓ 服务重启成功"
else
    echo "✗ 错误:服务重启失败"
    systemctl status "$SERVICE" | head -20
    exit 1
fi

使用建议

  1. 生产环境优先使用 Systemd Timer 方案
  2. 测试环境可使用 Cron + Bash 脚本
  3. 脚本应包含完善的日志和错误处理
  4. 重启前最好做依赖检查
  5. 配置监控告警,异常时及时通知

根据你的具体需求(定时频率、服务类型、环境要求),可以选择最适合的方案,需要调整具体的定时时间或服务类型告诉我即可。

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