摘要:前言在使用整合定時任務,發現當某個定時任務執行出現執行時間過長的情況時會阻塞其他定時任務的執行。問題定位后續通過翻查的文檔以及打印日志輸出當前線程信息得知問題是由于默認使用只要個線程處理定時任務。問題復盤需要注意示例的版本為。
前言
在使用Springboot整合定時任務,發現當某個定時任務執行出現執行時間過長的情況時會阻塞其他定時任務的執行。
問題定位后續通過翻查Springboot的文檔以及打印日志(輸出當前線程信息)得知問題是由于Springboot默認使用只要1個線程處理定時任務。
問題復盤需要注意示例的Springboot版本為2.1.3.RELEASE。
關鍵pom文件配置定時任務...省略非關鍵配置 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** * 定時任務 * @author RJH * create at 2019-03-29 */ @Component public class SimpleTask { private static Logger logger= LoggerFactory.getLogger(SimpleTask.class); /** * 執行會超時的任務,定時任務間隔為5000ms(等價于5s) */ @Scheduled(fixedRate = 5000) public void overtimeTask(){ try { logger.info("current run by overtimeTask"); //休眠時間為執行間隔的2倍 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 正常的定時任務 */ @Scheduled(fixedRate = 5000) public void simpleTask(){ logger.info("current run by simpleTask"); } }啟動類
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class TaskDemoApplication { public static void main(String[] args) { SpringApplication.run(TaskDemoApplication.class, args); } }運行結果
...省略非關鍵信息 2019-03-29 21:22:38.410 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:38.413 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:22:48.413 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:48.414 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:22:58.418 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:58.418 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:23:08.424 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:23:08.424 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:23:18.425 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:23:18.426 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask ...結果分析
由運行結果可以看出:
每次定時任務的運行都是由scheduling-1這個線程處理
正常運行的simpleTask被overtimeTask阻塞導致了運行間隔變成了10秒
后面通過查閱Springboot的文檔也得知了定時任務默認最大運行線程數為1。
解決方案由于使用的Springboot版本為2.1.3.RELEASE,所以有兩種方法解決這個問題
使用Springboot配置在配置文件中可以配置定時任務可用的線程數:
## 配置可用線程數為10 spring.task.scheduling.pool.size=10自定義定時任務的線程池
使用自定義的線程池代替默認的線程池
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * 定時任務配置類 * @author RJH * create at 2019-03-29 */ @Configuration public class ScheduleConfig { /** * 此處方法名為Bean的名字,方法名無需固定 * 因為是按TaskScheduler接口自動注入 * @return */ @Bean public TaskScheduler taskScheduler(){ // Spring提供的定時任務線程池類 ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler(); //設定最大可用的線程數目 taskScheduler.setPoolSize(10); return taskScheduler; } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74002.html
摘要:也是自帶的一個基于線程池設計的定時任務類。其每個調度任務都會分配到線程池中的一個線程執行,所以其任務是并發執行的,互不影響。 原創不易,如需轉載,請注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責任!!! 一、在JAVA開發領域,目前可以通過以下幾種方式進行定時任務 1、單機部署模式 Timer:jdk中...
摘要:定時任務間隔時間方式執行一次定時任務線程休眠規定時間類類允許調度一個任務。引入依賴配置測試執行一次定時任務使用注解是為定時任務而生的一個注解,查看注解的源碼表達式接收一個。 本文旨在用通俗的語言講述枯燥的知識 定時任務作為一種系統調度工具,在一些需要有定時作業的系統中應用廣泛,如每逢某個時間點統計數據、在將來某個時刻執行某些動作...定時任務在主流開發語言均提供相應的API供開發者調用...
摘要:構建工程創建一個工程,在它的程序入口加上開啟調度任務。創建定時任務創建一個定時任務,每過在控制臺打印當前時間。通過在方法上加注解,表明該方法是一個調度任務。 這篇文章將介紹怎么通過spring去做調度任務。 構建工程 創建一個Springboot工程,在它的程序入口加上@EnableScheduling,開啟調度任務。 @SpringBootApplication @EnableSch...
摘要:而我這里定時任務的觸發是要通過接口的方式來觸發,所以只用實現以下的調度器即可。我這里簡單說下任務的調度器,具體的任務類,觸發器,任務什么時候執行是由它決定的。遇到的坑解決方式這個是因為不兼容的問題,所以使用是不會出現這個錯誤的。 實現定時任務的幾種方式: 1.使用linux的crontab 優點: 1.使用方式很簡單,只要在crontab中寫好 2.隨時可以修改,不需要...
閱讀 1273·2021-11-23 09:51
閱讀 1633·2021-11-16 11:45
閱讀 4050·2021-10-09 09:43
閱讀 2691·2021-07-22 16:47
閱讀 951·2019-08-27 10:55
閱讀 3454·2019-08-26 17:40
閱讀 3093·2019-08-26 11:39
閱讀 3235·2019-08-23 18:39