本文目录导读:

我来提供一个功能完善的定时重启服务脚本,包含多种实现方式。
方案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
使用建议
- 生产环境优先使用 Systemd Timer 方案
- 测试环境可使用 Cron + Bash 脚本
- 脚本应包含完善的日志和错误处理
- 重启前最好做依赖检查
- 配置监控告警,异常时及时通知
根据你的具体需求(定时频率、服务类型、环境要求),可以选择最适合的方案,需要调整具体的定时时间或服务类型告诉我即可。