首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Spring 定時任務 @Scheduled 不執行排查清單:配置、掃描、線程池全解析

     編輯:程式設計綜合問答

現象確認

配置了 <task:annotation-driven/> 和 @Scheduled(cron="0/5 * * * * ?"),但任務方法不執行,無報錯日誌。

排查清單(按可能性排序)

1. 組件掃描缺失 @Component/@Service


// 必須加在類上,否則 Spring 不會創建 Bean,自然不會解析 @Scheduled
@Component
public class TaskJob {
    @Scheduled(cron = "0/5 * * * * ?")
    public void job() { ... }
}

確認 <context:component-scan base-package="com.tc.mytask"/> 覆蓋該類包路徑。

2. 配置文件未被加載

  • web.xml 中 ContextLoaderListener 加載的配置文件路徑正確?
  • Spring Boot 應用主類 @EnableScheduling 是否啟用?

3. 線程池配置問題

默認單線程執行,若任務耗時超過間隔或拋異常,後續任務會阻塞/停止。


@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar registrar) {
        registrar.setTaskScheduler(taskScheduler());
    }
    
    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 核心線程數
        scheduler.setThreadNamePrefix("scheduled-");
        scheduler.setErrorHandler(t -> log.error("定時任務異常", t)); // 關鍵:異常處理
        return scheduler;
    }
}

4. Cron 表達式語法錯誤


// 正確:每5秒
"0/5 * * * * ?"
// 錯誤寫法示例
"*/5 * * * * ?"  // Spring 不支持秒級 *
"0 0/5 * * * ?"  // 這是每5分鐘

5. 方法簽名限制

  • 必須是 public void 無參方法
  • 不能是 static(除非配置 proxyTargetClass)
  • 所在類不能是 final

6. 事務/代理干擾

若類上有 @Transactional,CGLIB 代理可能導致 @Scheduled 失效。解決:將定時任務類單獨拆分,或使用 @EnableAsync + @Async 異步執行。

驗證步驟

  1. 啟動日誌搜索 ScheduledAnnotationBeanPostProcessor 確認註冊
  2. 斷點調試 ScheduledTaskRegistrar#scheduleTasks
  3. 臨時改為 fixedRate=5000 排除 Cron 解析問題
  4. 查看 org.springframework.scheduling DEBUG 日誌

官方參考實現

Spring 官方指南:https://spring.io/guides/gs/scheduling-tasks/

系統檢查以上 6 點,99% 可定位 @Scheduled 不執行根因。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved