linux定时任务“时间漂移”主因是cron仅按计划点尝试触发,不保证准时:脚本超时致串行延迟、ntp校时致跳过任务、系统负载高致fork延迟、时区不一致致认知偏差。

Linux定时任务出现“时间漂移”,通常不是cron本身变慢或走不准,而是任务执行时机与预期不符——比如本该每5分钟跑一次的脚本,实际间隔变成5分10秒甚至更长。根本原因在于cron的设计逻辑:它只负责“在指定时间点尝试触发”,并不保证准时、不排队、不阻塞。
任务执行耗时超过调度周期
这是最常见原因。例如设置 */5 * * * * /path/to/script.sh,但脚本平均运行6分钟。cron不会跳过、取消或并发执行,而是等上一次结束才启动下一次,导致后续所有执行时间整体后移。
- 检查脚本真实耗时:time /path/to/script.sh
- 避免在周期性任务中做重IO、网络等待或未设超时的操作
- 若必须长时间运行,改用后台守护(如systemd service)+内部循环,而非依赖cron频率
cron守护进程重启或系统时间跳变
cron每次读取crontab是“按需加载”:修改后重载,或自身崩溃重启时重新扫描。若此时系统时间被NTP大幅校正(如回拨10秒),cron可能跳过一个或多个计划点——因为它内部用的是“下次应执行时间 = 上次 + 周期”,时间倒退会让计算结果失效。
- 用 systemctl status cron 查看是否近期重启过
- 检查NTP日志:journalctl -u systemd-timesyncd | grep -i "step\|adjust"
- 关键任务建议加时间兜底判断,比如脚本开头检查 date +%s 是否距预期窗口偏差过大
系统负载高或资源受限导致延迟启动
cron本身轻量,但fork/exec子进程依赖系统空闲资源。当CPU持续100%、内存严重swap、或进程数接近ulimit上限时,cron可能无法及时创建新进程,表现为“到了时间却没执行”,几秒到几十秒后才补上。
- 监控系统负载:uptime 和 cat /proc/loadavg
- 限制脚本资源使用,例如用 timeout 300 nice -n 19 ionice -c 3 包裹命令
- 避免在高峰时段密集调度多个重量级任务
时区配置不一致引发误解
cron默认使用系统本地时区(/etc/localtime),但用户查看日志、设置crontab或脚本内调用date时,可能用了UTC或其他时区,造成“明明设了02:00,怎么凌晨4点才跑”的错觉。
- 确认cron使用的时区:grep -i zone /var/log/syslog | tail -5(Debian/Ubuntu)或 journalctl -u crond | grep -i zone(RHEL/CentOS)
- 统一方式:在crontab文件顶部加 TZ=Asia/Shanghai(需系统支持)
- 脚本内显式指定时区:export TZ=Asia/Shanghai; date










