很多站点的定时任务是在上线那天随手加上的:备份数据库、生成站点地图、清理缓存、同步外部数据。加上之后很少有人再回头看,直到某天站点变慢或者磁盘写满,才发现某个任务已经连着跑了好几天。
定时任务为什么会拖慢整站
定时任务和访客请求共用同一台服务器的资源。CPU、内存、磁盘 IO、数据库连接数,总量都是有限的。一个任务如果比预期慢十倍,它占用的资源就会一直存在,访客请求只能排队等。
- 导出类任务走了全表扫描,长时间占着数据库连接不放
- 备份任务反复压缩大文件,磁盘 IO 被打满
- 循环抓取外部接口却没有超时设置,一个任务挂着不结束
- 每分钟执行一次的任务,实际跑完要三分钟,实例不断堆积
- 日志只写不清理,几个月后把磁盘占满
自查要看的几件事
任务清单和执行频率
先把服务器上的任务列出来:crontab、systemd timer、主机面板里的计划任务,还有应用层自己的调度(部分 CMS 和插件也会写任务)。每一项都要能说清楚三件事:做什么、多久跑一次、正常情况下跑完要多久。
执行记录与退出状态
只记录“开始执行”意义不大。要能查到每次任务的开始时间、结束时间、退出码和输出内容。如果日志里只有一行启动信息,出问题时你无法判断它是卡住了,还是早就失败退出了。
是否允许并发
有些任务本身不支持同时跑两个实例,比如全量备份、索引重建、数据对账。如果没加锁,上一次还没结束,下一次又启动了,轻则输出互相覆盖,重则把数据写乱。
超时和重试
涉及网络请求的任务必须设超时。重试也要有上限和间隔,否则一个外部接口挂掉之后,你的任务可能在几分钟内发出成百上千次请求,把对方和自己的带宽都拖下水。
一个可执行的排查顺序
- 列出全部任务,标注频率、预计耗时、最近一次的实际耗时
- 找出实际耗时远大于预计耗时的任务,先翻它的日志
- 对照任务运行时段,看服务器负载(CPU、内存、磁盘、连接数)有没有同步抬升
- 检查同一个任务是否出现了重叠执行
- 检查日志文件、临时文件、备份文件的占用情况
- 确认失败任务有没有告警,第二天有没有人会发现
常见的处置方式
- 把耗时长的任务挪到访问低谷时段,并彼此错开时间
- 加互斥锁或重入判断,保证同一任务不会重叠执行
- 给外部请求设超时和重试上限
- 日志按天切分,并设置保留天数
- 给关键任务加告警:失败、超时、耗时异常都要能通知到人
- 已经不需要的任务直接删掉,不要留在那里当隐患
定时任务的隐患往往不是“从来不跑”,而是“一直在跑但没跑完”。前者容易被发现,后者只会慢慢消耗资源。
小结
定时任务属于平时没人注意、出问题时影响面却很大的东西。建议每季度过一遍任务清单,确认每一项还有存在的必要、跑得完、有日志、失败有人知道。做到这几点,多数由定时任务引起的负载问题都能提前避开。