定时任务与巡检脚本
High Contrast
Dark Mode
Light Mode
Sepia
Forest
2 min read466 words

定时任务与巡检脚本

脚本只有被稳定执行,才真的算自动化。

自动化结构

graph LR A[cron / systemd.timer] --> B[巡检/备份脚本] B --> C[日志落地] C --> D{执行成功?} D -->|否| E[告警通知] D -->|是| F[记录成功时间]

cron 常用任务调度

# 编辑当前用户的 crontab
crontab -e
# 格式:分 时 日 月 周  命令
# ┌───────────── 分钟 (0-59)
# │ ┌─────────── 小时 (0-23)
# │ │ ┌───────── 日 (1-31)
# │ │ │ ┌─────── 月 (1-12)
# │ │ │ │ ┌───── 星期 (0-7, 0和7都是周日)
# │ │ │ │ │
# * * * * *  命令
# 实际任务示例
0  2 * * *   /opt/scripts/backup_db.sh >> /var/log/backup.log 2>&1   # 每日 2:00 备份
*/5 * * * *  /opt/scripts/check_disk.sh >> /var/log/disk_check.log 2>&1  # 每 5 分钟磁盘检查
0  3 * * 0   /opt/scripts/cleanup_logs.sh                             # 每周日 3:00 清理日志
0  1 1 * *   /opt/scripts/monthly_report.sh                           # 每月 1 日 1:00 月报

巡检任务频率建议:

任务 频率 原因
磁盘空间检查 每 5–15 分钟 磁盘满会导致服务立即崩溃
健康检查 每 1–5 分钟 及早发现进程崩溃
数据库备份 每日 RPO 通常是 24 小时
日志清理 每日或每周 防止磁盘被日志撑满
SSL 证书检查 每日 提前 30 天告警,避免证书过期

实用巡检脚本示例

#!/usr/bin/env bash
# check_health.sh — 应用健康巡检(适合放入 cron 每 5 分钟)
set -euo pipefail
HEALTH_URL=http://127.0.0.1:3000/health
DISK_WARN_PCT=80
ALERT_WEBHOOK="${ALERT_WEBHOOK:-}"   # Slack/飞书 Webhook(可选)
LOG=/var/log/myapp/health_check.log
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
alert() {
log "[ALERT] $*"
[[ -n "$ALERT_WEBHOOK" ]] && \
curl -sf -X POST -H 'Content-type: application/json' \
-d "{\"text\":\"[ALERT] $*\"}" "$ALERT_WEBHOOK" || true
}
# 1. 应用健康检查
if ! curl -sf --max-time 5 "$HEALTH_URL" > /dev/null; then
alert "应用健康检查失败: $HEALTH_URL"
else
log "应用健康检查 OK"
fi
# 2. 磁盘空间检查
DISK_PCT=$(df / --output=pcent | tail -1 | tr -d ' %')
if (( DISK_PCT >= DISK_WARN_PCT )); then
alert "磁盘使用率 ${DISK_PCT}%,超过阈值 ${DISK_WARN_PCT}%"
else
log "磁盘使用率 ${DISK_PCT}% OK"
fi
# 3. 关键进程检查
if ! systemctl is-active --quiet myapp; then
alert "myapp 服务未运行"
fi

cron vs systemd.timer 对比

特性 cron systemd.timer
配置位置 crontab -e / /etc/cron.d/ /etc/systemd/system/*.timer
错过执行(机器宕机期间) 丢失,不补跑 Persistent=true 开机后补跑
日志 重定向到文件(自行管理) journalctl -u myservice
依赖管理 支持 After=, Requires=
随机延迟(防止雷同) 不支持 RandomizedDelaySec=
现代推荐程度 传统,仍广泛使用 推荐(Ubuntu 16.04+)

systemd.timer 示例(备份任务):

# /etc/systemd/system/backup.service
[Unit]
Description=Database Backup
[Service]
Type=oneshot
User=root
ExecStart=/opt/scripts/backup_db.sh
StandardOutput=journal
StandardError=journal
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true           # 机器宕机后开机补跑
RandomizedDelaySec=5min   # 随机延迟 0–5 分钟,防止多台机器同时备份
[Install]
WantedBy=timers.target
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer    # 查看下次执行时间
journalctl -u backup.service -n 20   # 查看上次执行日志

常见误区

误区 正确做法
cron 任务没有 2>&1 重定向 stderr 默认通过 sendmail 发送,没有 sendmail 则静默丢失
cron 脚本使用相对路径 cron 环境没有 PATH,必须用绝对路径(/usr/bin/python3 而非 python3
任务失败了没人知道 加告警通知(Webhook)或检查 cron 日志(/var/log/cron
systemd.timer 不加 Persistent=true 机器维护期间的备份窗口将被永久跳过

本节执行清单

下一节幂等性、重试与日志规范——自动化脚本也需要工程质量。