【Springboot知識】Springboot計劃任務Schedule詳解

文章目錄

  • Spring Boot 定時任務從原理到實現詳解
    • 一、核心原理分析
      • 1. 架構分層
      • 2. 核心組件
      • 3. 線程模型
    • 二、基礎實現步驟
      • 1. 添加依賴
      • 2. 主類配置
      • 3. 定時任務類
    • 三、高級配置技巧
      • 1. 自定義線程池
      • 2. 動態配置參數
      • 3. 分布式鎖集成(Redis示例)
    • 四、異常處理機制
      • 1. 統一異常處理器
      • 2. 任務重試機制
    • 五、監控與調試
      • 1. Actuator 端點
      • 2. 性能監控
    • 六、完整示例項目結構
    • 七、最佳實踐建議
    • Schedule注解參數詳細說明
      • 一、注解基礎參數詳解
        • 1. 核心參數配置
        • 2. 參數對照表
      • 二、Cron表達式詳解
        • 1. 標準格式
        • 2. 特殊字符說明
        • 3. 常用表達式示例
      • 三、多模式配置示例
        • 1. 基礎模式組合
        • 2. 動態參數注入
      • 四、高級使用技巧
        • 1. 多任務并行執行
        • 2. 條件化調度
        • 3. 分布式鎖集成
      • 五、異常處理機制
        • 1. 自定義異常處理器
        • 2. 重試機制
      • 六、常見問題解決方案
        • 1. 任務不執行排查
        • 2. 多實例重復執行
      • 七、最佳實踐建議

Spring Boot 定時任務從原理到實現詳解

一、核心原理分析

1. 架構分層

graph TDA[Application] --> B[@EnableScheduling]B --> C[ScheduledAnnotationBeanPostProcessor]C --> D[TaskScheduler]D --> E[ThreadPoolTaskScheduler]D --> F[ConcurrentTaskScheduler]

2. 核心組件

  • @EnableScheduling:啟用定時任務自動配置
  • ScheduledAnnotationBeanPostProcessor:解析@Scheduled注解
  • TaskScheduler:任務調度接口
  • CronTrigger:處理cron表達式

3. 線程模型

// 默認線程池配置
public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupportimplements TaskScheduler, SchedulingTaskExecutor {private volatile int poolSize = 1; // 默認單線程private ThreadFactory threadFactory = new CustomizableThreadFactory("task-scheduler-");
}

二、基礎實現步驟

1. 添加依賴

<!-- pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>

2. 主類配置

@SpringBootApplication
@EnableScheduling
public class SchedulingApplication {public static void main(String[] args) {SpringApplication.run(SchedulingApplication.class, args);}
}

3. 定時任務類

@Component
public class ScheduledTasks {private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);// 固定頻率(任務開始時間間隔)@Scheduled(fixedRate = 5000)public void fixedRateTask() {log.info("Fixed Rate Task :: Execution Time - {}", LocalDateTime.now());}// 固定延遲(任務結束時間間隔)@Scheduled(fixedDelay = 7000, initialDelay = 2000)public void fixedDelayTask() {log.info("Fixed Delay Task :: Execution Time - {}", LocalDateTime.now());}// Cron表達式@Scheduled(cron = "0 0/15 9-17 * * MON-FRI")public void cronTask() {log.info("Cron Task :: Execution Time - {}", LocalDateTime.now());}
}

三、高級配置技巧

1. 自定義線程池

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setPoolSize(5);taskScheduler.setThreadNamePrefix("custom-scheduler-");taskScheduler.initialize();taskRegistrar.setTaskScheduler(taskScheduler);}
}

2. 動態配置參數

application.properties
schedule.rate=10000
schedule.delay=5000
schedule.cron=0 0 8 * * *
@Scheduled(fixedRateString = "${schedule.rate}")
public void dynamicRateTask() {// ...
}@Scheduled(cron = "${schedule.cron}")
public void dynamicCronTask() {// ...
}

3. 分布式鎖集成(Redis示例)

@Scheduled(fixedRate = 10000)
public void distributedTask() {String lockKey = "scheduledTaskLock";String requestId = UUID.randomUUID().toString();try {if (redisLockUtil.tryGetLock(lockKey, requestId, 30)) {log.info("Acquired lock, executing task...");// 業務邏輯}} finally {redisLockUtil.releaseLock(lockKey, requestId);}
}

四、異常處理機制

1. 統一異常處理器

@ControllerAdvice
public class SchedulingExceptionHandler {@ExceptionHandler(TaskExecutionException.class)public void handleTaskException(TaskExecutionException ex) {log.error("Scheduled task failed: {}", ex.getMessage());// 發送告警通知}
}

2. 任務重試機制

@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
@Scheduled(fixedRate = 5000)
public void retryableTask() {// 可能失敗的業務邏輯if (Math.random() > 0.5) {throw new RuntimeException("Simulated error");}
}

五、監控與調試

1. Actuator 端點

management.endpoints.web.exposure.include=scheduledtasks

訪問 /actuator/scheduledtasks 查看任務列表:

{"cron": [{"runnable": {"target": "com.example.ScheduledTasks.cronTask"},"expression": "0 0/15 9-17 * * MON-FRI"}]
}

2. 性能監控

@Scheduled(fixedRate = 5000)
@Timed(value = "scheduled.task", description = "監控任務執行時間")
public void monitoredTask() {// 業務邏輯
}

六、完整示例項目結構

scheduling-demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/
│   │   │       ├── config/
│   │   │       │   └── SchedulerConfig.java
│   │   │       ├── ScheduledTasks.java
│   │   │       └── SchedulingApplication.java
│   │   └── resources/
│   │       ├── application.properties
│   │       └── logback-spring.xml
│   └── test/
└── pom.xml

七、最佳實踐建議

  1. 線程池配置原則

    # 推薦線程數 = CPU核心數 * 2(IO密集型)
    # 推薦線程數 = CPU核心數 + 1(計算密集型)
    
  2. 任務設計規范

    • 單任務執行時間 < 調度間隔時間
    • 添加事務邊界控制
    • 避免任務間狀態共享
  3. 生產環境注意事項

    // 添加健康檢查
    @Component
    public class ScheduleHealthIndicator implements HealthIndicator {@Overridepublic Health health() {// 檢查任務最后執行時間return Health.up().build();}
    }
    

通過以上配置和實現,可以構建出高可靠、易維護的定時任務系統。定時任務的執行頻率需要根據實際業務需求進行合理設置,同時要特別注意在分布式環境下的任務協調問題。

Schedule注解參數詳細說明

一、注解基礎參數詳解

1. 核心參數配置
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {String cron() default "";String zone() default "";long fixedDelay() default -1;String fixedDelayString() default "";long fixedRate() default -1;String fixedRateString() default "";long initialDelay() default -1;String initialDelayString() default "";
}
2. 參數對照表
參數名稱類型必填默認值說明
cronString“”Unix風格的cron表達式
zoneString“”時區ID(如"Asia/Shanghai")
fixedDelaylong-1上次執行結束到下次執行的間隔(毫秒)
fixedDelayStringString“”支持占位符的字符串形式(如"${schedule.delay}")
fixedRatelong-1固定頻率執行(毫秒)
fixedRateStringString“”支持占位符的字符串形式
initialDelaylong-1首次執行的延遲時間(毫秒)
initialDelayStringString“”支持占位符的字符串形式

二、Cron表達式詳解

1. 標準格式
秒(0-59) 分(0-59) 時(0-23) 日(1-31) 月(1-12) 周(0-7) 年(可選)
2. 特殊字符說明
字符含義示例說明
*任意值0 * * * * *每分鐘0秒執行
?不指定(僅日/周字段)0 0 0 ? * MON每周一0點執行
-范圍0 0 9-17 * * *每天9點到17點整點執行
,多個值0 0 8,12,18 * * *每天8、12、18點執行
/間隔頻率0 0/15 * * * *每15分鐘執行一次
L最后一天/最后一周0 0 0 L * ?每月最后一天0點執行
W最近工作日0 0 0 LW * ?每月最后一個工作日執行
#第幾個周幾0 0 0 ? * 5#2每月第2個周四執行
3. 常用表達式示例
@Scheduled(cron = "0 0 3 * * ?")      // 每天凌晨3點執行
@Scheduled(cron = "0 0/5 9-17 * * MON-FRI") // 工作日9-17點每5分鐘執行
@Scheduled(cron = "0 0 12 1 * ?")    // 每月1號中午12點執行
@Scheduled(cron = "0 0 8 L * ?")      // 每月最后一天上午8點執行

三、多模式配置示例

1. 基礎模式組合
// 初始延遲3秒,之后每5秒執行
@Scheduled(initialDelay = 3000, fixedRate = 5000) // 每天8:30執行(使用屬性配置)
@Scheduled(cron = "${app.schedule.daily-report}") 
2. 動態參數注入
application.properties
schedule.interval=5000
schedule.initial.delay=10000
schedule.cron.expression=0 0/15 * * * *
@Scheduled(fixedRateString = "${schedule.interval}",initialDelayString = "${schedule.initial.delay}"
)
public void dynamicScheduleTask() {// 業務邏輯
}@Scheduled(cron = "${schedule.cron.expression}")
public void cronTask() {// 定時任務
}

四、高級使用技巧

1. 多任務并行執行
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5);scheduler.setThreadNamePrefix("schedule-pool-");scheduler.initialize();taskRegistrar.setTaskScheduler(scheduler);}
}
2. 條件化調度
@Profile("production")  // 僅生產環境生效
@ConditionalOnProperty(name = "scheduler.enabled", havingValue = "true")
@Scheduled(fixedRate = 10000)
public void conditionalTask() {// 生產環境專用任務
}
3. 分布式鎖集成
@Scheduled(cron = "0 0/30 * * * ?")
public void distributedTask() {String lockKey = "reportGenerationLock";try {if (redisLock.tryLock(lockKey, 300)) { // 獲取30秒鎖generateReport();}} finally {redisLock.release(lockKey);}
}

五、異常處理機制

1. 自定義異常處理器
@ControllerAdvice
public class ScheduleExceptionHandler {@ExceptionHandler(ScheduleExecutionException.class)public void handleScheduleException(ScheduleExecutionException ex) {log.error("定時任務執行失敗: {}", ex.getMessage());// 發送告警通知alertService.sendAlert("Schedule Failure", ex.getMessage());}
}
2. 重試機制
@Retryable(value = {DataAccessException.class},maxAttempts = 3,backoff = @Backoff(delay = 1000, multiplier = 2)
)
@Scheduled(fixedDelay = 5000)
public void retryableTask() {// 可能失敗的數據操作databaseService.batchUpdate();
}

六、常見問題解決方案

1. 任務不執行排查
1. 檢查主類是否添加`@EnableScheduling`
2. 確認任務方法為`public`修飾
3. 驗證cron表達式有效性(可用在線驗證工具)
4. 檢查線程池是否被占滿(默認單線程)
2. 多實例重復執行
// 使用數據庫鎖方案示例
@Transactional
@Scheduled(cron = "0 0 3 * * ?")
public void exclusiveTask() {LocalDateTime now = LocalDateTime.now();ScheduleLock lock = lockRepo.findByTaskName("dailyCleanup");if (lock == null || lock.getLockUntil().isBefore(now)) {// 獲取鎖(設置30分鐘有效期)lockRepo.save(new ScheduleLock("dailyCleanup", now.plusMinutes(30)));// 執行任務dataCleanupService.cleanup();// 釋放鎖lockRepo.deleteById("dailyCleanup");}
}

七、最佳實踐建議

  1. 線程池配置原則

    # 推薦配置公式
    IO密集型任務:線程數 = CPU核心數 * 2
    計算密集型任務:線程數 = CPU核心數 + 1
    
  2. 執行時間監控

    @Scheduled(fixedRate = 60000)
    public void monitoredTask() {StopWatch watch = new StopWatch();try {watch.start();// 業務邏輯} finally {watch.stop();if (watch.getTotalTimeMillis() > 5000) {log.warn("任務執行超時: {}ms", watch.getTotalTimeMillis());}}
    }
    
  3. 重要任務日志規范

    @Scheduled(cron = "0 0 2 * * ?")
    public void criticalTask() {log.info("==== 開始執行數據歸檔任務 ====");try {archiveService.archiveData();log.info("數據歸檔成功,歸檔數量: {}", count);} catch (Exception e) {log.error("數據歸檔失敗", e);throw e;} finally {log.info("==== 結束數據歸檔任務 ====");}
    }
    

通過合理配置和遵循最佳實踐,可以構建出高可靠、易維護的定時任務系統。特別注意在分布式環境下做好任務協調,避免重復執行導致的數據不一致問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904229.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904229.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904229.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL:聯合查詢

目錄 一、笛卡爾積 ?二、內連接 三、外連接 &#xff08;1&#xff09;左外連接 &#xff08;2&#xff09;右外連接 &#xff08;3&#xff09;全外連接 四、自連接 五、子查詢 &#xff08;1&#xff09;單行子查詢 &#xff08;2&#xff09;多行子查詢 &…

深入理解 Cortex-M3 的內核寄存器組

每個 MCU 開發工程師一定都了解寄存器這個東西&#xff0c;以 STM32 為例&#xff0c;其擁有非常多的外設模塊&#xff0c;如串口、SPI、IIC 等等&#xff0c;如果要使用這些外設&#xff0c;使其按照我們的要求工作&#xff0c;就需要配置這些外設的寄存器&#xff0c;往這些寄…

網絡安全自動化:找準邊界才能筑牢安全防線

數字時代&#xff0c;企業每天要面對成千上萬的網絡攻擊。面對龐大的服務器群、分散的團隊和長期不重啟的設備&#xff0c;很多企業開始思考&#xff1a;哪些安全操作適合交給機器自動處理&#xff1f;哪些必須由人工把關&#xff1f;今天我們就用大白話聊聊這件事。 一、這些事…

C++負載均衡遠程調用學習之負載均衡算法與實現

目錄 01 lars 系統架構回顧 02 lars-lbAgentV0.4-route_lb處理report業務流程 03 lars-lbAgentV0.4-負責均衡判斷參數配置 04 lars-lbAgentV0.4-負載均衡idle節點的失敗率判斷 05 lars-lbAgentV0.4-負載均衡overload節點的成功率判斷 06 lars-lbAgentV0.4-負載均衡上報提交…

領略算法真諦: 多源bfs

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

雷電模擬器-超好用的Windows安卓模擬器

一、雷電模擬器介紹 雷電模擬器是一款功能強大的軟件&#xff0c;它能夠在電腦上模擬出安卓手機系統&#xff0c;讓你可以在電腦上運行各類手機應用及游戲。其采用虛擬安卓手機操作界面&#xff0c;為玩家帶來了獨特的體驗。 &#xff08;一&#xff09;強大的兼容性 雷電模擬…

文章三《機器學習基礎概念與框架實踐》

文章3:機器學習基礎概念與框架實踐 ——從理論到代碼,用Scikit-learn構建你的第一個分類模型 一、機器學習基礎理論:三大核心類型 機器學習是人工智能的核心,通過數據讓計算機自動學習規律并做出預測或決策。根據學習方式,可分為三類: 1. 監督學習(Supervised Learni…

腦機接口技術:開啟人類與機器的全新交互時代

在科技飛速發展的今天&#xff0c;人類與機器的交互方式正經歷著前所未有的變革。從最初的鍵盤鼠標&#xff0c;到觸摸屏&#xff0c;再到語音控制&#xff0c;每一次交互方式的升級都極大地提升了用戶體驗和效率。如今&#xff0c;腦機接口&#xff08;Brain-Computer Interfa…

8.2 GitHub企業級PDF報告生成實戰:ReportLab高級技巧與性能優化全解析

GitHub企業級PDF報告生成實戰:ReportLab高級技巧與性能優化全解析 GitHub Sentinel 高級功能實現:PDF 報告生成技術詳解 關鍵詞:PDF 報告生成, ReportLab 實戰, 結構化數據轉換, 容器化字體配置, 企業級報告模板 1. 需求分析與技術選型 PDF 報告生成需要滿足以下技術要求…

架構思維:構建高并發讀服務_基于流量回放實現讀服務的自動化測試回歸方案

文章目錄 引言一、升級讀服務架構&#xff0c;為什么需要自動化測試&#xff1f;二、自動化回歸測試系統&#xff1a;整體架構概覽三、日志收集1. 攔截方式2. 存儲與優化策略3. 架構進化 四、數據回放技術實現關鍵能力 五、差異對比對比方式靈活配置 六、三種回放模式詳解1. 離…

基于Spring Boot 3.0、ShardingSphere、PostgreSQL或達夢數據庫的分庫分表

要實現基于Spring Boot 3.0、ShardingSphere、PostgreSQL或達夢數據庫的分庫分表&#xff0c;首先需要對ShardingSphere進行一些基本配置。你提到的溯源碼、批次號等數據需要考慮到跨年數據的存儲&#xff0c;因此要設計一個能夠動態擴展的分表策略 添加ShardingSphere依賴 在…

位運算的應用

1. 判斷偶數&#xff0c;判斷最低位是0還是1即可&#xff0c;?求模快 x % 2 ! 0 //x正負都可以判斷&#xff1b;不?x%2 1&#xff0c;因為如果x為負奇數&#xff0c;x%2-1 (x & 0x1) 0 例如&#xff1a; int x; int main() { cin>>x; if((x & 0x1)0) cout<…

FOC算法開環控制基礎

1. 為什么要有FOC算法 先看看從有刷電機到無刷電機的簡單介紹&#xff0c;如下圖1&#xff0c;通電螺線圈會產生磁場&#xff0c;這個磁場會產生N級和S級&#xff0c;然后這個電磁鐵就可以吸引永磁體&#xff0c;S級吸引N級&#xff0c;N級吸引S級&#xff0c;通俗的來說&…

【計算機網絡】HTTP中GET和POST的區別是什么?

從以下幾個方面去說明&#xff1a; 1.定義 2.參數傳遞方式 3.安全性 4.冪等性 1.定義&#xff1a; GET&#xff1a; 獲取資源&#xff0c;通常請求數據而不改變服務器的狀態。POST&#xff1a; 提交數據到服務器&#xff0c;通常會改變服務器的狀態或副作用(如創建或更新資源…

7400MB/s5050TBW完美結合,全新希捷酷玩530R SSD體驗評測

7400MB/s&5050TBW完美結合&#xff0c;全新希捷酷玩530R SSD體驗評測 哈嘍小伙伴們好&#xff0c;我是Stark-C~ 說到希捷酷玩530 SSD&#xff0c;很多硬核進階玩家應該都知道&#xff0c;或者說正在使用&#xff08;比如說我~&#xff09;。 作為希捷大廠旗下高性能SSD的…

(undone) MIT6.S081 2023 學習筆記 (Day11: LAB10 mmap)

url: https://pdos.csail.mit.edu/6.1810/2023/labs/mmap.html mmap和munmap系統調用允許UNIX程序對其地址空間進行精細控制。它們可用于進程間共享內存、將文件映射到進程地址空間&#xff0c;并作為用戶級頁面錯誤處理方案的一部分&#xff0c;例如課程中討論的垃圾回收算法。…

Q_OBJECT宏的作用

Qt 中&#xff0c;如果一個類中定義了信號&#xff08;signals&#xff09;或槽&#xff08;slots&#xff09;&#xff0c;那么這個類必須包含 Q_OBJECT 宏。 Q_OBJECT宏是 Qt 元對象系統的核心部分&#xff0c;它使得信號和槽機制能夠正常工作。 Q_OBJECT宏是 Qt 的元對象系統…

信息安全基石:加解密技術的原理、應用與未來

信息加解密技術是信息安全領域的核心技術之一&#xff0c;以下為你詳細介紹&#xff1a; 一、加密技術 1.定義&#xff1a;加密是通過特定的算法和密鑰&#xff0c;將原始的明文信息轉化為看似無意義的密文信息的過程。這一過程使得信息在傳輸、存儲等過程中&#xff0c;即使…

LeetCode:返回倒數第k個結點

1、題目描述 實現一種算法&#xff0c;找出單向鏈表中倒數第 k 個節點。返回該節點的值。 注意&#xff1a;本題相對原題稍作改動 示例&#xff1a; 輸入&#xff1a; 1->2->3->4->5 和 k 2 輸出&#xff1a; 4 說明&#xff1a; 給定的 k 保證是有效的。 2、…

R004 -計算機硬件基礎

目錄 1.數據表示&計算機網絡組成 2.計算機網絡分類 3.馮諾依曼體系結構 4.指令系統基礎 5.指令系統類型 6.流水線技術 流水線周期 &#xff1a;各流水段中&#xff0c;執行時間最長的那一段。就是T 流水線時間&#xff1a;t 1t2t 3 (n-1) * T 7.流水線指標 8.存儲系…