這篇文章帶給大家的內容是關於Springboot定時任務遇到的問題解決,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
前言:在使用Springboot整合定時任務,發現當某個定時任務執行出現執行時間過長的情況時會阻塞其他定時任務的執行。
問題定位
後續透過翻查Springboot的文檔以及列印日誌(輸出當前執行緒資訊)得知問題是由於Springboot預設使用只要1個執行緒處理定時任務。
問題複盤
需要注意範例的Springboot版本為2.1.3.RELEASE。
關鍵pom檔案設定
<!--继承父项目--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> ...省略非关键配置 <!-- 引入依赖--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
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
,所以有兩種方法可以解決這個問題
在設定檔中可以配置定時任務可用的執行緒數:
## 配置可用线程数为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; } }
這篇文章到這裡就已經全部結束了,更多其他精彩內容可以關注PHP中文網的Java視頻教程欄目!
以上是Springboot定時任務遇到的問題解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!