如何解決異步線程導(dǎo)致的traceId為空的問題
更新時間:2025年02月07日 08:37:29 作者:從int開始
文章討論了在使用異步線程時,traceId為空的問題,并提出了使用線程池的解決方案,作者分享了個人經(jīng)驗,并鼓勵大家參考和支持腳本之家
異步線程導(dǎo)致的traceId為空問題
1. 使用線程池
import lombok.Data; import org.slf4j.MDC; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * xxx任務(wù)線程池配置 */ @Configuration @ConfigurationProperties(prefix = "thread-pool.x-xx") @Data public class XxxThreadPoolConfiguration { /** * Minimum number of threads to keep alive */ private int corePoolSize = 8; /** * Maximum number of threads in the pool */ private int maxPoolSize = 16; /** * Time in seconds to keep excess idle threads alive */ private long keepAliveTime = 60; /** * queue size */ private int queueSize = 1000; @Bean("xXxExecutor") public ThreadPoolExecutor xXxExecutor() { ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<>(queueSize)); executor.setThreadFactory(runnable -> { Thread thread = new Thread(runnable); thread.setName("commonExecutor-" + thread.getId()); return thread; }); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); return executor; } public static class MdcThreadPoolExecutor extends ThreadPoolExecutor { public MdcThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void beforeExecute(Thread t, Runnable r) { // 在任務(wù)執(zhí)行前,從當(dāng)前線程(如果是主線程調(diào)用的話,就是主線程的MDC)獲取traceId并設(shè)置到即將執(zhí)行任務(wù)的線程的MDC中 String traceId = MDC.get("traceId"); MDC.put("traceId", traceId); super.beforeExecute(t, r); } @Override protected void afterExecute(Runnable r, Throwable t) { // 任務(wù)執(zhí)行后清除MDC中的traceId(避免內(nèi)存泄漏等問題,釋放資源) MDC.remove("traceId"); super.afterExecute(r, t); } } }
2. 使用
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service public class XxxController{ // 構(gòu)造器注入 public OutChargeOrderPushController( @Qualifier("xXxExecutor")ThreadPoolExecutor executor ) { this.executor = executor; } // 使用異步操作方法的時候把executor 傳進(jìn)去即可 }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
idea之Recompile、Rebuild和Build之間的區(qū)別及說明
這篇文章主要介紹了idea之Recompile、Rebuild和Build之間的區(qū)別及說明,具有很好的參考價值,希望對有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08Java關(guān)于List集合去重方案詳細(xì)介紹
實際項目開發(fā)中,很多業(yè)務(wù)場景下都會遇見集合去重。在說到List集合去重之前,首先我們回顧下普通類型的list如何去重2021-09-09SpringBoot整合Echarts繪制靜態(tài)數(shù)據(jù)柱狀圖和餅圖
這篇文章給大家介紹了SpringBoot整合Echarts繪制靜態(tài)數(shù)據(jù)柱狀圖和餅圖,文中通過代碼示例給大家介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2024-03-03Java使用Jdbc連接Oracle執(zhí)行簡單查詢操作示例
這篇文章主要介紹了Java使用Jdbc連接Oracle執(zhí)行簡單查詢操作,結(jié)合實例形式詳細(xì)分析了java基于jdbc實現(xiàn)Oracle數(shù)據(jù)庫的連接與查詢相關(guān)操作技巧,需要的朋友可以參考下2019-09-09Java實現(xiàn)為Word每一頁設(shè)置不同圖片水印的效果
Word中設(shè)置水印時,可加載圖片設(shè)置為水印效果,但通常添加水印效果時,會對所有頁面都設(shè)置成統(tǒng)一效果。所以本文為大家介紹了一個方法,可以實現(xiàn)對每一頁或者某個頁面設(shè)置不同的水印效果,需要的可以參考一下2022-02-02SpringBoot參數(shù)驗證的幾種方式小結(jié)
在日常的接口開發(fā)中,為了防止非法參數(shù)對業(yè)務(wù)造成影響,經(jīng)常需要對接口的參數(shù)進(jìn)行校驗,例如登錄的時候需要校驗用戶名和密碼是否為空,所以本文介紹了SpringBoot參數(shù)驗證的幾種方式,需要的朋友可以參考下2024-07-07