从零搭建开发脚手架 异步线程池场景下增强Trace功能

从零搭建开发脚手架 异步线程池场景下增强Trace功能

前言

下面两篇文章是之前写的trace功能的基础和原理。

但是在业务中有异步线程场景下,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:异步导致子线程丢掉了父线程中的userIdtraceId
  • 问题2:异步导致子线程和父线程使用的不是一个Trace对象,即上面日志中1部分和2部分割裂现象

增强

解决上面的问题其实很简单,只需在异步时处理下,把父线程的threadlocal中的值手动复制到子线程中去,并且在使用完毕后清除即可

伪代码

// 父线程信息
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
今日推荐