⏰ 第07章 · 定时任务实战
本服务器 cron + 日志
定时任务实战¶
这一章把 cron 用到这台服务器的真实场景上,讲几种"跑得稳"的写法:登录脚本、生成监控报告、备份、以及如何保证"只会跑一次""失败能知道"。学完你就能自己写出一套可靠的定时任务。
真实场景 1:每日自动化签到(本机示例)¶
贴吧签到脚本每天 07:00 执行:
0 7 * * * TIEBA_QUIET=1 /usr/bin/python3 /root/scripts/tieba_sign.py >> /var/log/tieba_sign.log 2>&1
要点:
TIEBA_QUIET=1:脚本里检测到该变量后只输出关键结果,不刷屏(适合 cron 后台跑)。- 重定向到日志文件:
>>追加覆盖可保留历史,>会清空。 - 用
2>&1把错误也收进去,避免"静默失败"。
真实场景 2:生成并推送监控报告(本机示例)¶
监控报告脚本每天 08:00 执行:
0 8 * * * /usr/bin/python3 /root/scripts/monitor_report.py >> /var/log/monitor_report.log 2>&1
该脚本读取 /root/.feishu_monitor.conf 拿到飞书 Webhook/凭证,从 Prometheus 取数、画图、传给飞书群。日志里能看到它是否成功发送。
真实场景 3:定时备份¶
备份是最该自动化的事。示例(每天 02:00,先建目录再 mysqldump 导出全库):
mkdir -p /backups/mysql
0 2 * * * mkdir -p /backups/mysql && mysqldump --all-databases > /backups/mysql/all_$(date +\%F).sql
注意 | cron 里的
%是特殊字符,要写成\%。date +\%F才能正确输出日期。建议把备份写成独立脚本,方便做"启动前清理旧备份、压缩、校验"。
更好的备份脚本 backup.sh:
#!/bin/bash
set -euo pipefail
BACKUP_DIR=/backups/mysql
mkdir -p "$BACKUP_DIR"
STAMP=$(date +%F_%H%M)
mysqldump --all-databases | gzip > "$BACKUP_DIR/all_${STAMP}.sql.gz"
# 只保留最近 7 份
find "$BACKUP_DIR" -name '*.sql.gz' -mtime +7 -delete
# 写日志
echo "backup ok $STAMP" >> /var/log/backup.log
并在 crontab 里:
0 2 * * * /bin/bash /root/scripts/backup.sh >> /var/log/backup.log 2>&1
真实场景 4:用 flock 防止任务重叠(关键!)¶
万一前一分钟的任务没跑完,下一分钟又开一个,会并发出错。用 flock 加锁,保证同一时间只有一个实例:
#!/bin/bash
exec flock -n /tmp/myjobs.lock /bin/bash /root/scripts/monitor_report.py
crontab 配上即可:
0 8 * * * flock -n /tmp/mon_report.lock /usr/bin/python3 /root/scripts/monitor_report.py >> /var/log/monitor_report.log 2>&1
重要 | 长时间任务(拉取数据、生成大数据)一定要加锁,否则上次任务还在跑,下次又启动,轻则资源占满,重则数据错乱。
真实场景 5:失败告警¶
cron 不会主动告诉你任务失败,所以要在脚本里"出错即告知"或"写失败标记":
#!/bin/bash
out=$(/usr/bin/python3 /root/scripts/tieba_sign.py 2>&1)
code=$?
echo "$out" >> /var/log/tieba_sign.log
if [ $code -ne 0 ]; then
echo "myscript failed: $out" | mail -s "任务失败" you@example.com
fi
版本化与可维护性¶
- 脚本统一放
/root/scripts/(集中管理)。 - 每个脚本开头写清"用途 / 依赖 / 用法 / 配置位置"(参考本机这两个脚本的文件头注释)。
- 日志统一放
/var/log/并配logrotate(见《Linux 系统运维 · 日志管理》)防磁盘打满。 - 用
systemd timer也能替代 cron:需要"上次运行时间""失败重试"等高级特性时再上。
相关命令¶
crontab -l/crontab -e管理;systemctl status cron看服务。flock防并发;date +\%F生成日期标签。find ... -mtime +N -delete清理过期备份。mail -s/飞书/钉钉 Webhook 做失败通知。