SpringBoot如何自定義線程池配置類
更新時間:2024年04月02日 16:18:09 作者:ABin-阿斌
有時候我們在項目中做一些長鏈路的跑批任務(wù)時,基于Springboot項目的定時任務(wù),我們可以指定一個自定義的線程配置類進行單獨提供給具體跑批任務(wù)使用,而不占用整個系統(tǒng)資源,這篇文章主要介紹了SpringBoot如何自定義線程池配置類,需要的朋友可以參考下
一、前言
- 有時候我們在項目中做一些長鏈路的跑批任務(wù)時,基于Springboot項目的定時任務(wù),我們可以指定一個自定義的線程配置類進行單獨提供給具體跑批任務(wù)使用,而不占用整個系統(tǒng)資源。
二、案例展示
- 我們觀察一下第一種方式和優(yōu)化后的對比在哪里,關(guān)鍵點什么?
1、初始版本
@Configuration @EnableAsync public class ScheduledConfig { /** * 創(chuàng)建并配置一個線程池,用于快速執(zhí)行任務(wù)。 * * @return Executor 返回一個配置好的線程池實例,可以用于快速執(zhí)行任務(wù)。 */ @Bean("baseExecutor") public Executor fastExecutor() { // 創(chuàng)建 ThreadPoolTaskExecutor 實例 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 設(shè)置線程名前綴 executor.setThreadNamePrefix("xxxx-schedule-baseExecutor"); // 設(shè)置最大線程池大小 executor.setMaxPoolSize(10); // 設(shè)置核心線程池大小 executor.setCorePoolSize(8); // 設(shè)置隊列容量 executor.setQueueCapacity(5); // 設(shè)置拒絕執(zhí)行處理器,采用CallerRunsPolicy策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; }
2、代碼審核意見和優(yōu)化建議
3、潛在問題和風險
- 異常處理: 線程池的默認異常處理機制可能不足以處理所有任務(wù)拋出的異常。盡管設(shè)置了CallerRunsPolicy作為拒絕執(zhí)行處理器,它僅在線程池飽和時工作,并不直接處理任務(wù)執(zhí)行中的異常。建議增強異常處理邏輯,例如通過自定義的RejectedExecutionHandler實現(xiàn)或者在任務(wù)代碼中加入更細粒度的異常處理。
- 資源泄露: 當應(yīng)用停止時,如果線程池沒有被正確關(guān)閉,可能會導(dǎo)致資源泄露。雖然Spring通常會管理Bean的生命周期,但最好確認ThreadPoolTaskExecutor的實例是否加入了適當?shù)匿N毀邏輯,例如調(diào)用executor.shutdown()。
- 線程數(shù)配置: CorePoolSize被設(shè)置為8,MaxPoolSize被設(shè)置為10,這意味著在高負載情況下,線程池只能擴展到10個線程。這樣的配置可能不足以處理所有高峰時段的請求。你需要根據(jù)實際的負載測試結(jié)果調(diào)整這些參數(shù)。
- 隊列容量: 隊列容量被固定為5。這意味著一旦隊列滿了,即使線程池還沒有達到最大大小,任務(wù)也會被拒絕執(zhí)行。根據(jù)實際的負載情況,考慮適當增加隊列容量或調(diào)整線程池的大小。
4、優(yōu)化建議
- 性能監(jiān)控: 考慮添加監(jiān)控機制來跟蹤線程池的性能指標,如活躍線程數(shù)、隊列大小和拒絕執(zhí)行的任務(wù)數(shù)等。這有助于及時發(fā)現(xiàn)和調(diào)整配置參數(shù),以保證系統(tǒng)的穩(wěn)定性。
- 可調(diào)整性: 考慮將線程池的配置參數(shù)(如corePoolSize, maxPoolSize, queueCapacity等)設(shè)置為可從外部配置(例如應(yīng)用配置文件)的方式獲取。這樣可以在不修改代碼的情況下調(diào)整這些參數(shù),以適應(yīng)不同的運行環(huán)境。
- 定制化: 如果有更復(fù)雜的需求,比如需要執(zhí)行周期性任務(wù)或需要更細粒度的控制任務(wù)執(zhí)行,可以考慮使用Spring提供的其他任務(wù)調(diào)度組件,如 ScheduledThreadPoolExecutor 或者集成 Quartz 等第三方庫。
5、優(yōu)化后的代碼
@Configuration @EnableAsync public class ExecutorConfig { // 名字可以根據(jù)項目業(yè)務(wù)隨意起 @Bean("baseExecutor") public Executor fastExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 線程名前綴保持不變 executor.setThreadNamePrefix("xxxx-schedule-base"); // 調(diào)整核心線程池大小、最大線程池大小和隊列容量,以適應(yīng)可能的更高負載 executor.setCorePoolSize(16); // 增加核心線程數(shù) executor.setMaxPoolSize(20); // 增加最大線程數(shù) executor.setQueueCapacity(100); // 增加隊列容量 // 使用自定義的RejectedExecutionHandler來處理任務(wù)被拒絕的情況 executor.setRejectedExecutionHandler(new CustomRejectedExecutionHandler()); // 確保在應(yīng)用停止時線程池能被正確關(guān)閉 Runtime.getRuntime().addShutdownHook(new Thread(() -> { executor.shutdown(); })); return executor; } // 自定義的拒絕執(zhí)行處理器,以更好地處理任務(wù)被拒絕的情況 static class CustomRejectedExecutionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 這里可以加入更詳細的日志記錄或發(fā)送警報等邏輯 System.out.println("Task " + r.toString() + " rejected from executor " + executor.toString()); } } }
三、具體使用
@Async("baseExecutor") @Scheduled(cron = "0 0/5 * * * ?"){ // 具體業(yè)務(wù) }
到此這篇關(guān)于SpringBoot如何自定義線程池配置類的文章就介紹到這了,更多相關(guān)SpringBoot線程池配置類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus如何關(guān)閉SQL日志打印詳解
在使用mybatisplus進行開發(fā)時,日志是一個非常有用的工具,它可以幫助我們更好地了解和調(diào)試我們的代碼,這篇文章主要給大家介紹了關(guān)于MyBatis-Plus如何關(guān)閉SQL日志打印的相關(guān)資料,需要的朋友可以參考下2024-03-03關(guān)于SpringBoot中事務(wù)失效的幾種情況
這篇文章主要介紹了關(guān)于SpringBoot中事務(wù)失效的幾種情況,Spring AOP默認使用動態(tài)代理,會給被代理的類生成一個代理類,事務(wù)相關(guān)的操作都通過代理來完成,使用內(nèi)部方法調(diào)用時,使用的是實例調(diào)用,沒有通過代理類調(diào)用方法,因此事務(wù)不會檢測到失敗,需要的朋友可以參考下2023-08-08Spring?Security方法級安全控制@PreAuthorize注解的靈活運用小結(jié)
本文將帶著大家講解?@PreAuthorize?注解的核心原理、SpEL?表達式機制,并通過的示例代碼演示如何在實際項目中靈活運用該注解實現(xiàn)細粒度的權(quán)限控制,感興趣的朋友一起看看吧2025-04-04Java基礎(chǔ)強化訓(xùn)練輸入錯誤即結(jié)束進程
本文主要介紹了Java編程的基礎(chǔ)知識強化應(yīng)用,文中實例涉及到了許多基礎(chǔ)知識,new對象,控制臺輸入,if語句等。很實用,需要的朋友可以參考下2017-09-09Java 微信公眾號開發(fā)相關(guān)總結(jié)
公眾號作為主流的自媒體平臺,有著不少人使用。這次以文本回復(fù)作為案例來講解Java相關(guān)的微信公眾號開發(fā)2021-05-05Spring Cloud之遠程調(diào)用OpenFeign參數(shù)傳遞
本文介紹了Spring Cloud中使用OpenFeign進行遠程調(diào)用時,參數(shù)傳遞的不同方式,包括傳遞單個參數(shù)、多個參數(shù)、對象和JSON數(shù)據(jù),感興的朋友一起看看吧2025-03-03