问题分析
在高并发情况下,我们没办法快速定位用户在一次请求中对应的所有日志,或者说是定位某个用户操作的所有日志,在追踪用户行为或排查生产问题会显得十分棘手,那是因为我们在输出的日志的时候没把请求的唯一标示或者说是用户身份标示输出到我们的日志中,导致我们没办法根据一个请求或者用户身份标识来做日志的过滤。
解决方案
我们在记录日志的时候把请求的唯一标识(sessionId)或者身份标识(userId) 记录到日志中这个问题就可以得到很好的解决了(本文使用UUID)并在每次输出log的时候将这个UUID输出到日志中。
知识点
- MDC
- Spring拦截器(HandlerInterceptor)
- Spring Cloud Feign拦截器(RequestInterceptor)
- Spring Cloud Hystrix的隔离策略
- 以上知识点详细各位同学可自行补习
引入JAR包
<!--spring拦截器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<!-- feign请求拦截 -->
<dependency>
<groupId>com.moonciki.strongfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.2.3</version>
</dependency>
<!-- hystrix线程池隔离工具包 -->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.12</version>
</dependency>
MDC
- MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。
实现拦截器LogInterceptor
/**
* @Author
* @Date 2020/12/10
* @Description 通过拦截器高并发场景下日志打印线程ID
*/
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
//线程ID常量
private static final String THREAD_ID = "THREAD_ID";
/**
* controller方法前调用
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)