diff --git a/blade-service/logpm-factory/src/main/java/com/logpm/factory/config/ExecutorConfig.java b/blade-service/logpm-factory/src/main/java/com/logpm/factory/config/ExecutorConfig.java new file mode 100644 index 000000000..66138ba55 --- /dev/null +++ b/blade-service/logpm-factory/src/main/java/com/logpm/factory/config/ExecutorConfig.java @@ -0,0 +1,82 @@ +package com.logpm.factory.config; + +import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.ThreadLocalUtil; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskDecorator; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@Slf4j +@EnableAsync +public class ExecutorConfig { + + @Bean + public Executor asyncExecutor() { + log.info("start async executor"); + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); +// 配置核心线程数 + threadPoolTaskExecutor.setCorePoolSize(10); +// 配置最大线程数 + threadPoolTaskExecutor.setMaxPoolSize(20); +// 配置队列大小 + threadPoolTaskExecutor.setQueueCapacity(50); +// 配置线程池中线程的名称前缀 + threadPoolTaskExecutor.setThreadNamePrefix("ASYNC_THREAD_"); +// HelloWorldServiceImpl rejection-policy: 当pool已经达到max size时,如何处理新任务: +// CallerRunsPolicy: 不在新线程中执行任务,而是由调用者所在的线程来执行; +// AbortPolicy: 拒绝执行新任务,并抛出RejectedExecutionException异常; +// DiscardPolicy:丢弃当前将要加入队列的任务; +// DiscardOldestPolicy:丢弃任务队列中最旧的任务; + threadPoolTaskExecutor.setRejectedExecutionHandler( + new ThreadPoolExecutor.CallerRunsPolicy() + ); + threadPoolTaskExecutor.setTaskDecorator(new ContextCopyingDecorator()); + threadPoolTaskExecutor.initialize(); + return threadPoolTaskExecutor; + } + + + static class ContextCopyingDecorator implements TaskDecorator { + @Nonnull + @Override + public Runnable decorate(@Nonnull Runnable runnable) { + RequestAttributes context = RequestContextHolder.currentRequestAttributes(); + String tenantId = AuthUtil.getTenantId(); + Map all = ThreadLocalUtil.getAll(); + Map mdcMap = MDC.getCopyOfContextMap(); + return () -> { + try { + all.keySet().forEach(key -> ThreadLocalUtil.put(key, all.get(key))); + if (mdcMap != null && !mdcMap.isEmpty()) { + MDC.setContextMap(mdcMap); + } + RequestContextHolder.setRequestAttributes(context); + String tenantId1 = AuthUtil.getTenantId(); + + runnable.run(); + } finally { + RequestContextHolder.resetRequestAttributes(); + all.clear(); + if (mdcMap != null) { + mdcMap.clear(); + } + ThreadLocalUtil.clear(); + MDC.clear(); + } + }; + } + } + +}