凌晨 2 点,运维群炸了:结算任务超时,数据库连接池打满,CPU 飙到 95%。查了半天发现 —— 上一轮的账单还没算完,下一轮又启动了,数据重复处理、死锁、OOM,一波带走。 这不是段子。只要你的系统有定时任务,这个坑迟早会踩进去。 今天这篇文章,从根因到方案,从单机到分布式,把定时任务重叠执行这件事讲透。 一、问题到底出在哪? 先看一个最简单的场景。 // 每 5 分钟执行一次数据同步 @Scheduled(cron = "0 */5 * * * ?") public void syncData() { // 从上游拉数据、清洗、入库 pullData(); // 耗时:不固定,2~8 分钟 cleanData(); saveToDB(); } 调度周期是 5 分钟,但 pullData() 本身就要 2~8 分钟。问题来了: 8:05 第一轮启动,预计 8:13 结束 8:10 第二轮启动,此时第一轮还没跑完 两轮并行执行,同时操作同一批数据 后果你懂的:数据重复、死锁、连接池耗尽、OOM,一条龙服务。 根因一句话:调度频率 > 任务执行耗时,且没有任何防护机制。 ....
