@Scheduled 定时任务不执行?八成是这 4 个问题

@Scheduled 定时任务不执行?八成是这 4 个问题

导读

求职招聘系统里定时任务不少:简历解析完重试、职位过期自动下架、零点结算日结工资。Spring Boot 的 @Scheduled 看着简单,加个注解就完事,但线上不执行、重复执行、执行一半挂掉,都是坑。这篇把我踩过的坑整理下。

坑一:默认单线程,任务互相堵死

这是最隐蔽的坑。Spring 的 @Scheduled 默认只有一个线程,所有定时任务共用。你的任务 A 跑 10 秒,任务 B 到点了也得排队等 A 跑完。

我遇到过一次:职位过期下架任务里调了个慢接口,阻塞了 30 秒,结果零点工资结算任务跟着延迟了 30 秒,用户投诉"工资没到账"。

解法:配置线程池。

java 复制代码
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }
}

每个任务各跑各的,互不干扰。

坑二:cron 表达式写错,任务永远不触发

cron 是 6 位(秒 分 时 日 月 周),跟 Linux 的 5 位不一样。我刚开始写 0 0 0 * * * 想每天零点执行,结果发现是 5 位,Spring 直接启动报错,但报错在日志里很不显眼,你不翻日志根本不知道任务没注册上。

正确写法:

java 复制代码
@Scheduled(cron = "0 0 0 * * ?")  // 每天 0 点
@Scheduled(cron = "0 */5 * * * ?") // 每 5 分钟

周字段用 ? 不用 *,这是新手最容易错的地方。

坑三:集群部署任务重复执行

本地开发没事,一上集群,每个节点都在跑定时任务,工资结算执行了 3 次,用户收到 3 次到账通知。这问题必须解决。

方案一是用分布式锁(Redis):

java 复制代码
@Scheduled(cron = "0 0 0 * * ?")
public void dailySettle() {
    Boolean locked = redisTemplate.opsForValue()
        .setIfAbsent("lock:dailySettle", "1", Duration.ofMinutes(30));
    if (!Boolean.TRUE.equals(locked)) {
        log.info("其他节点正在执行,跳过");
        return;
    }
    try {
        // 业务逻辑
    } finally {
        redisTemplate.delete("lock:dailySettle");
    }
}

方案二是让定时任务只在一个节点跑(配个开关,只有一台机器开 @Scheduled)。我后来用了 Redis 锁,因为配置开关容易忘,锁更保险。

坑四:任务内部异常,不打印就静默

@Scheduled 方法里抛异常,如果方法没 try-catch,日志默认只打一行 ERROR,堆栈还不全,排查全靠猜。更坑的是,异常不影响下一次触发,所以任务会"看起来在跑,实际每次都失败"。

我的习惯:

java 复制代码
@Scheduled(cron = "0 0 2 * * ?")
public void retryResumeParse() {
    log.info("简历解析重试任务开始");
    try {
        doRetry();
    } catch (Exception e) {
        log.error("简历解析重试任务失败", e); // 堆栈打全
    }
}

而且重试任务我还会给每条数据记状态(重试次数、下次重试时间),而不是整个任务一把梭,这样单条失败不会影响其他数据。

总结

@Scheduled 的坑基本都是"看着没跑,其实跑了"或者"跑了没结果"。配线程池、写对 cron、加分布式锁、内部 try-catch 打全日志,这四件事做完,定时任务基本就稳了。现在我做定时任务,第一件事就是先写 cron 验证工具确认表达式没错,再往里填业务。

相关推荐
szephyr2 天前
用 Python 写自动化脚本:定时任务、文件批处理、自动出报表
python·自动化·pandas·脚本·定时任务
boomworks12 天前
【定时执行专家】进程检测、重启、关闭功能使用说明
进程管理·定时任务·定时执行·进程重启·结束进程脚本
FungLeo1 个月前
Node 后端实战 · 边缘 Cron 定时任务怎么写?Cloudflare 三个实战任务与踩坑
serverless·边缘计算·定时任务·cloudflare·cron·workers
凤山老林1 个月前
Spring Boot 定时任务进阶:动态 Cron 与集群防重实战
java·spring boot·后端·定时任务·集群定时任务
仙逆GPT2 个月前
Codex定时任务怎么设置?ChatGPT Plus用Worktree自动巡检项目
chatgpt·定时任务·codex·git worktree·chatgpt plus
CodexDave2 个月前
Python 自动化接单实战(七):定时报告如何保证同一天只生成一次
python自动化·定时任务·报表生成·幂等执行
豆瓣鸡2 个月前
XXL-JOB 定时任务——从 Docker 部署到分片广播,分布式任务调度落地
spring boot·分布式·docker·定时任务
Anastasiozzzz2 个月前
从单机定时到分布式调度:深度剖析 XXL-JOB 的架构设计、核心机制与生产实战
定时任务
小森林之主3 个月前
秒级定时任务速查手册:核心语法与实用示例
定时任务·cron·定时调度·速查手册·秒级定时