站点运营

站点运营:定时任务自查,别让一个卡死的 cron 拖住整站

定时任务平时不起眼,出问题时却可能持续占用数据库连接、磁盘 IO 和 CPU。本文给出站点运营中定时任务的自查思路:任务清单与频率、执行日志与退出状态、并发与加锁、超时与重试,以及常见的处置方式。

站点运营

站点运营:定时任务自查,别让一个卡死的 cron 拖住整站

很多站点的定时任务是在上线那天随手加上的:备份数据库、生成站点地图、清理缓存、同步外部数据。加上之后很少有人再回头看,直到某天站点变慢或者磁盘写满,才发现某个任务已经连着跑了好几天。

定时任务为什么会拖慢整站

定时任务和访客请求共用同一台服务器的资源。CPU、内存、磁盘 IO、数据库连接数,总量都是有限的。一个任务如果比预期慢十倍,它占用的资源就会一直存在,访客请求只能排队等。

  • 导出类任务走了全表扫描,长时间占着数据库连接不放
  • 备份任务反复压缩大文件,磁盘 IO 被打满
  • 循环抓取外部接口却没有超时设置,一个任务挂着不结束
  • 每分钟执行一次的任务,实际跑完要三分钟,实例不断堆积
  • 日志只写不清理,几个月后把磁盘占满

自查要看的几件事

任务清单和执行频率

先把服务器上的任务列出来:crontab、systemd timer、主机面板里的计划任务,还有应用层自己的调度(部分 CMS 和插件也会写任务)。每一项都要能说清楚三件事:做什么、多久跑一次、正常情况下跑完要多久。

执行记录与退出状态

只记录“开始执行”意义不大。要能查到每次任务的开始时间、结束时间、退出码和输出内容。如果日志里只有一行启动信息,出问题时你无法判断它是卡住了,还是早就失败退出了。

是否允许并发

有些任务本身不支持同时跑两个实例,比如全量备份、索引重建、数据对账。如果没加锁,上一次还没结束,下一次又启动了,轻则输出互相覆盖,重则把数据写乱。

超时和重试

涉及网络请求的任务必须设超时。重试也要有上限和间隔,否则一个外部接口挂掉之后,你的任务可能在几分钟内发出成百上千次请求,把对方和自己的带宽都拖下水。

一个可执行的排查顺序

  1. 列出全部任务,标注频率、预计耗时、最近一次的实际耗时
  2. 找出实际耗时远大于预计耗时的任务,先翻它的日志
  3. 对照任务运行时段,看服务器负载(CPU、内存、磁盘、连接数)有没有同步抬升
  4. 检查同一个任务是否出现了重叠执行
  5. 检查日志文件、临时文件、备份文件的占用情况
  6. 确认失败任务有没有告警,第二天有没有人会发现

常见的处置方式

  • 把耗时长的任务挪到访问低谷时段,并彼此错开时间
  • 加互斥锁或重入判断,保证同一任务不会重叠执行
  • 给外部请求设超时和重试上限
  • 日志按天切分,并设置保留天数
  • 给关键任务加告警:失败、超时、耗时异常都要能通知到人
  • 已经不需要的任务直接删掉,不要留在那里当隐患
定时任务的隐患往往不是“从来不跑”,而是“一直在跑但没跑完”。前者容易被发现,后者只会慢慢消耗资源。

小结

定时任务属于平时没人注意、出问题时影响面却很大的东西。建议每季度过一遍任务清单,确认每一项还有存在的必要、跑得完、有日志、失败有人知道。做到这几点,多数由定时任务引起的负载问题都能提前避开。