一个项目中既须要异步任务, 也须要调度任务, 想把这两个异步线程池分来就须要配置两个线程池。
调度任务添加 @Scheduled 注解, 须要异步执行的方法添加 @Async 注解java
中间遇到点小问题, 异步任务线程池老是不生效, 而是使用的调度任务线程池, 通过查文档不断尝试解决了.
公司利用 slf4j 的 MDC 作链路跟踪, 因此还须要添加前置操做, 使用 TaskDecorator 实现。spring
再次分享给你们以做备忘.json
代码以下:异步
AsyncConfig.javaasync
package com.ecej.esmart.autodispatch.config; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskDecorator; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.Map; import java.util.concurrent.Executor; @Slf4j @EnableAsync @Configuration public class AsyncConfig implements AsyncConfigurer { @Bean @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); executor.setThreadNamePrefix("async-pool-"); executor.setTaskDecorator(new MdcTaskDecorator()); executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; } class MdcTaskDecorator implements TaskDecorator { @Override public Runnable decorate(Runnable runnable) { Map<String, String> contextMap = MDC.getCopyOfContextMap(); Runnable runnable1 = new Runnable() { @Override public void run() { if (contextMap != null) { MDC.setContextMap(contextMap); } runnable.run(); } }; return runnable1; } } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (throwable, method, params) -> { log.error("异步任务异常:方法:{} 参数:{}", method.getName(), JSON.toJSONString(params)); log.error(throwable.getMessage(), throwable); }; } }
SchedulingConfig.javaide
package com.ecej.esmart.autodispatch.config; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @Slf4j @Configuration @EnableScheduling public class SchedulingConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { scheduledTaskRegistrar.setTaskScheduler(taskScheduler()); } @Bean(destroyMethod = "shutdown") public ThreadPoolTaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(5); scheduler.setThreadNamePrefix("dispatch-"); scheduler.setAwaitTerminationSeconds(600); scheduler.setErrorHandler(throwable -> log.error("调度任务发生异常", throwable)); scheduler.setWaitForTasksToCompleteOnShutdown(true); return scheduler; } }