定时任务失联需用crontab+flock+timeout三件套:flock防重叠执行,timeout控制时长并返回124码,失败时触发alarm.sh报警;同时显式声明PATH、重定向日志、确保脚本有执行权限并用env -i模拟crontab环境测试。
定时任务跑着跑着就失联了?不是没执行,就是卡住不动,或者多个实例同时跑把系统拖垮——这类问题在生产环境里太常见。光靠 crontab 本身远远不够,它只负责“按时喊一声”,不保证脚本是否真跑完、有没有卡死、会不会重复启动。要真正实现稳定、可监控、带报警的定时执行,得靠三件套配合:crontab 调度 + flock 互斥 + timeout 超时控制,再加一层轻量报警逻辑。
脚本运行时间波动大,比如网络抖动导致某次耗时翻倍,下一轮 crontab 又准时触发,结果两个实例同时读写同一份数据——轻则结果错乱,重则数据库锁表。flock 就是来解决这个的。
/var/run/mytask.lock)flock -n /var/run/mytask.lock -c 'bash /path/to/task.sh'
-n 表示非阻塞:如果锁已被占用,立刻退出,不等也不报错——crontab 自然就跳过这次执行有些脚本理论上几分钟能完,但偶发异常(如远端服务无响应、磁盘 IO 堵塞)可能卡十几分钟甚至更久。timeout 能主动掐断它,并返回明确状态码。
timeout -s TERM 300 bash /path/to/task.sh 表示最多运行5分钟,超时就发 TERM 信号终止光 kill 不够,得让人知道出事了。不需要接入复杂告警平台,一个简单脚本就能发邮件、写日志、甚至调用企业微信 webhook。
alarm.sh:记录时间、写入 /var/log/mytask-alarm.log,再用 mail -s "Task Timeout" [email protected] < /dev/stdin 发邮件*/10 * * * * flock -n /var/run/mytask.lock -c 'timeout -s TERM 600 /path/to/task.sh || /path/to/alarm.sh'
|| 表示前一条命令失败(返回非0)才执行 alarm.sh,正好覆盖超时和脚本内部报错两种场景很多“任务不执行”问题其实和 crontab 本身无关,而是环境差异导致的静默失败。
PATH=/usr/local/bin:/usr/bin:/bin
>/var/log/mytask.log 2>&1,避免邮件堆积或信息丢失#!/bin/bash,且确保有执行权限:chmod +x /path/to/task.sh
./task.sh,要用 env -i bash -c '/path/to/task.sh' 模拟 crontab 环境