springboot链路追踪ID
作者:互联网
1、实现拦截器,请求开始时候创建MDC值,结束后清理MDC值
2、实现线程池,将MDC上下文从主线程传递给子线程
拦截器:
import org.jetbrains.annotations.NotNull; import org.slf4j.MDC; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.UUID; /** * 拦截器 * * @author 许伟强51189 * @date 2022/5/25 10:41 */ public class TraceIdInterceptor implements HandlerInterceptor { public static final String UNIQUE_ID = "TRACE_ID"; public boolean preHandle(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse, @NotNull Object o) { MDC.put(UNIQUE_ID, UUID.randomUUID().toString()); return true; } public void postHandle(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse, @NotNull Object o, ModelAndView modelAndView) { } public void afterCompletion(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse, @NotNull Object o, Exception e) { MDC.clear(); } }
注册拦截器:
import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * TraceID的拦截器\生成請求的唯一值 * * @author 许伟强51189 * @date 2022/5/25 10:41 */ @Configuration public class TraceIdInterceptorConfiguration implements WebMvcConfigurer { @Value("${spring.traceIdInterceptor.enable:false}") private Boolean enable; @Value("${spring.traceIdInterceptor.addPathPatterns:/**}") private String[] addPathPatterns; @Value("${spring.traceIdInterceptor.excludePathPatterns:}") private String[] excludePathPatterns; @Override public void addInterceptors(@NotNull InterceptorRegistry interceptorRegistry) { if (!enable) { return; } TraceIdInterceptor myInterceptor = new TraceIdInterceptor(); interceptorRegistry.addInterceptor(myInterceptor).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns); } }
线程池:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /** * MdcThreadPoolConfiguration - 用于链路追踪MDC的线程池\在多线程情况下会将主线程的上下文传递给子线程 * * @author 许伟强51189 * @date 2022/5/25 16:50 */ @EnableAsync @Configuration public class MdcThreadPoolConfiguration { private int corePoolSize = 50; private int maxPoolSize = 200; private int queueCapacity = 1000; private int keepAliveSeconds = 300; @Bean(name = "threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(maxPoolSize); executor.setCorePoolSize(corePoolSize); executor.setQueueCapacity(queueCapacity); executor.setKeepAliveSeconds(keepAliveSeconds); executor.setTaskDecorator(new MdcTaskDecorator()); // 线程池对拒绝任务(无线程可用)的处理策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } }
上下文传递
/** * 任务适配器 * * @author 许伟强51189 * @version 2.0.0 * @date 2022/5/25 15:36 */ public class MdcTaskDecorator implements TaskDecorator { /** * 使异步线程池获得主线程的上下文 * * @param runnable * @return */ @Override public Runnable decorate(Runnable runnable) { Map<String, String> map = MDC.getCopyOfContextMap(); return () -> { try { MDC.setContextMap(map); runnable.run(); } finally { MDC.clear(); } }; } }
验证可用:
@Async("threadPoolTaskExecutor") public void getUserListAsyncThree(int page, int limit, String hash) { log.info("getUserListAsyncThree Thread Name:{}", Thread.currentThread().getName()); System.out.println(MDC.get(TraceIdInterceptor.UNIQUE_ID)); }
参考博客:
https://jishuin.proginn.com/p/763bfbd69eeb
标签:NotNull,springboot,MDC,链路,springframework,public,org,import,ID 来源: https://www.cnblogs.com/xuweiqiang/p/16310153.html