Python 定时任务调度指南
用 Python 调度定时任务的完整方案:系统 cron 最直接、python-crontab 编程管理、APScheduler 应用内调度,以及任务监控告警的配套实践。
直接回答:Python 定时任务有三条主流路线:操作系统 cron(最简单可靠)、python-crontab(用 Python 管理 crontab)、APScheduler(应用内调度,可动态增删)。按"任务属于系统还是属于应用"来选。
场景与选型
备份数据库、巡检服务、生成日报——到点自动跑的事都需要调度。三条路线的分工:
| 方案 | 适合 |
|---|---|
| 系统 cron | 独立脚本、系统级任务、最简单可靠 |
| python-crontab | 用代码批量管理 crontab 条目 |
| APScheduler | 与应用同生命周期、需动态调度、秒级精度 |
路线一:系统 cron
crontab -e
# 每天凌晨 3 点跑备份
0 3 * * * /usr/bin/python3 /opt/scripts/backup.py >> /var/log/backup.log 2>&1
cron 的可靠是三十年验证出来的:脚本崩溃不影响调度器本身,机器重启任务还在。记得:脚本内用绝对路径、输出重定向到日志文件。
路线二:python-crontab 编程管理
pip install python-crontab
from crontab import CronTab
cron = CronTab(user=True)
cron.remove_all(comment="weekly-report") # 只替换本部署管理的条目
job = cron.new(command="/usr/bin/python3 /opt/scripts/report.py",
comment="weekly-report")
job.setall("0 8 * * 1") # 每周一 8 点
cron.write()
# 管理已有任务
for job in cron:
print(job)
# 如需删除:cron.remove_all(comment="weekly-report"),随后 cron.write() 持久化
配置即代码:部署脚本顺带注册定时任务,服务器重建一键还原。
路线三:APScheduler 应用内调度
以下使用 APScheduler 3.x API(安装 apscheduler>=3.11,<4),不能直接套用到 4.x。sync_data、daily_report 是业务函数,主应用需持续运行并在退出时关闭调度器;此片段单独执行后主进程会立即结束。
from apscheduler.schedulers.background import BackgroundScheduler
sched = BackgroundScheduler()
sched.add_job(sync_data, "interval", minutes=30)
sched.add_job(daily_report, "cron", hour=8)
sched.start()
应用进程内的调度器:任务可动态增删改查、支持持久化、能直接用应用的连接与上下文。代价:进程挂了调度也停——Web 应用多副本时应让一个独立调度器实例负责发起任务。APScheduler 3.x 的多个调度器不能直接共享同一个持久化 job store 来实现高可用,还需要单实例管理或外部选主。
监控告警:被忽视的关键一环
定时任务最阴险的失败方式是静默不跑:cron 注释掉了、脚本路径错了、进程没起来——没有任何报错,直到有人发现报表两周没更新。
对策是"心跳式"监控:任务跑完后主动上报一次成功信号,监控端发现"超过周期没收到信号"即告警(死人的开关原理)。下面是自建心跳接口的示意地址,并非观测云 API。实际接入需按照所选监控服务配置认证、缺失数据规则、重试和上报失败日志,不能把业务成功与上报成功混为一谈:
import httpx
# 任务成功末尾:
response = httpx.post(
"https://monitor.example.com/heartbeat/backup-daily", timeout=5.0
)
response.raise_for_status()
如果任务已有完成日志,可将任务名、批次和结果采集到观测云,用日志检测检查成功记录是否按期出现。按任务周期加上允许延迟设置检测区间和数据断档规则,并分别模拟漏跑与上报失败,确认值班人收到的消息能区分两者。
常见问题(FAQ)
Q:cron 里脚本不执行最常见的原因?
A:环境变量——cron 的环境极简(PATH 都不全)。脚本里用绝对路径、显式 source 环境,或在 crontab 顶部补 PATH。
Q:任务执行时间超过间隔会怎样?
A:cron 会并发再启一个(脚本自己加锁防重,flock 一行搞定);APScheduler 可配 max_instances=1 与错过策略。
Q:时区坑怎么避?
A:cron 通常使用守护进程的系统时区,部分实现也支持 CRON_TZ,需核对运行环境;APScheduler 显式传 timezone="Asia/Shanghai"。服务器搬区、容器默认 UTC 时,定时任务时间全乱——应固定并验证实际调度时区,同时考虑夏令时影响。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。