如何解決異步線程導(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)文章
Java開發(fā)推薦使用的JDK版本以及對比詳細(xì)分析
這篇文章詳細(xì)分析了JDK17和JDK21作為當(dāng)前推薦版本的優(yōu)缺點,并對比了它們與JDK8和JDK11的差異,文中介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考借鑒價值,需要的朋友可以參考下2025-04-04
Java實現(xiàn)整合文件上傳到FastDFS的方法詳細(xì)
FastDFS是一個開源的輕量級分布式文件系統(tǒng),對文件進(jìn)行管理,功能包括:文件存儲、文件同步、文件上傳、文件下載等,解決了大容量存儲和負(fù)載均衡的問題。本文將提供Java將文件上傳至FastDFS的示例代碼,需要的參考一下2022-02-02
SpringBoot集成Druid實現(xiàn)監(jiān)控功能的示例代碼
這篇文章主要介紹了SpringBoot集成Druid實現(xiàn)監(jiān)控功能,Druid是阿里巴巴開發(fā)的號稱為監(jiān)控而生的數(shù)據(jù)庫連接池,可以很好的監(jiān)控DB池連接和SQL的執(zhí)行情況,天生就是針對監(jiān)控而生的DB連接池,文中通過代碼示例講解非常詳細(xì),需要的朋友可以參考下2024-02-02
JVM教程之Java代碼編譯和執(zhí)行的整個過程(二)
這篇文章主要介紹了JVM學(xué)習(xí)筆記第二篇,關(guān)于Java代碼編譯和執(zhí)行的整個過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
spring cloud gateway轉(zhuǎn)發(fā)服務(wù)報錯的解決
這篇文章主要介紹了spring cloud gateway轉(zhuǎn)發(fā)服務(wù)報錯的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

