비동기 스레드 풀 시나리오에서 추적 기능을 향상시키기 위해 처음부터 개발 스캐폴딩 구축

비동기 스레드 풀 시나리오에서 추적 기능을 향상시키기 위해 처음부터 개발 스캐폴딩 구축

머리말

다음 두 글은 이전에 작성한 trace 함수의 기본과 원리입니다.

그러나 비즈니스에 비동기 스레드가 있는 시나리오에서는 추적 기능에 약간의 결함이 있습니다. 자세한 내용은 다음 설명을 참조하십시오.

질문 샘플 코드

// 有个业务线程池
ThreadPoolExecutor pool = new EasyAdminThreadPoolExecutor(10,10,"laker");
// 模拟业务代码
public void pageList(){
    
    
    // 1.本地查询
    xxxService.pageList();
    // 2.模拟异步远程调用,耗时300ms
    pool.submit(() -> {
    
    
        TraceCodeBlock.trace("remoteService.call", value -> {
    
    
                    TimeUnit.MILLISECONDS.sleep(300);
            }); 
    }
    // 3.本地插入记录
    xxxService.insert();
}

결과 로그 :

// 1                     线程laker-9       丢掉了userId和traceId      
20:21:35.534  INFO --- [       laker-9] [|] com.laker.admin.framework.aop.trace.Trace:86 `---
    `---[302ms] Others-remoteService.call
// 2                    tomcat线程         userId=16还有traceId    
20:21:35.547  INFO --- [io-8080-exec-38] [16|497ef9d28d20452f84443c66c6f25354] com.laker.admin.framework.aop.trace.Trace:86 `---
    `---[428ms] Controller-ExtLeaveController|pageAll
        +---[max]:[414ms] Controller-ExtLeaveController.pageAll
        |   +---[32ms] Others-leaveService.page
        |   |   +---[3ms] Mapper-com.laker.admin.module.ext.mapper.ExtLeaveMapper.selectPage_mpCount
        |   |   `---[1ms] Mapper-com.laker.admin.module.ext.mapper.ExtLeaveMapper.selectPage

로그에 두 가지 문제가 있습니다.

  • 질문 1: 비동기로 인해 하위 스레드가 상위 스레드의 userId합계를 잃게 됩니다 traceId.
  • 질문 2: 비동기로 인해 하위 스레드와 상위 스레드가 Trace 개체를 사용하지 않습니다. 즉, 위 로그의 파트 1과 파트 2가 분할 됩니다 .

향상시키다

위의 문제를 해결하는 것은 실제로 매우 간단합니다. 비동기적으로 처리하고 부모 스레드의 스레드 로컬 값을 자식 스레드에 수동으로 복사하고 사용 후 지우십시오 .

의사 코드

// 父线程信息
userId/traceId/trace = LakerThreadlocal.get();
pool.submit(() -> {
    
    
 	  // 传递到子线程
      LakerThreadlocal.set(userId/traceId/trace);
      // 业务处理
      ......
      // 清空
      LakerThreadlocal.clear(); 
}

위의 의사 코드는 문제를 해결하기 위한 핵심 코드이며 이 논리를 EasyAdminMDCThreadPoolExecutor.java 에 캡슐화했습니다 .

사용자는 이전 스레드 풀만 수정하면 됩니다. 샘플 코드는 다음과 같습니다.

 ThreadPoolExecutor pool = new EasyAdminMDCThreadPoolExecutor(10,10,"laker");

이 때의 로그 효과는 다음과 같습니다.

20:21:35.547  INFO --- [io-8080-exec-38] [16|497ef9d28d20452f84443c66c6f25354] com.laker.admin.framework.aop.trace.Trace:86 `---
    `---[428ms] Controller-ExtLeaveController|pageAll
        +---[max]:[414ms] Controller-ExtLeaveController.pageAll
        |   +---[410ms] Others-leaveService.page
        |   |   +---[3ms] Mapper-com.laker.admin.module.ext.mapper.ExtLeaveMapper.selectPage_mpCount
        |   |   `---[1ms] Mapper-com.laker.admin.module.ext.mapper.ExtLeaveMapper.selectPage
        |   |   +---[302ms] Others-remoteService.call  // 这里是被修复处

전체 코드 주소 : https://gitee.com/lakernote/easy-admin

추천

출처blog.csdn.net/abu935009066/article/details/130175669