Créez un échafaudage de développement à partir de zéro pour améliorer la fonction Trace dans le scénario de pool de threads asynchrones

Créez un échafaudage de développement à partir de zéro pour améliorer la fonction Trace dans le scénario de pool de threads asynchrones

avant-propos

Les deux articles suivants sont la base et le principe de la fonction de trace écrite auparavant.

Cependant, dans le cas où il existe des threads asynchrones dans l'entreprise, la fonction de trace est un peu défectueuse, consultez la description suivante pour plus de détails.

Exemple de code de question

// 有个业务线程池
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();
}

Journal des résultats :

// 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

Nous voyons deux problèmes avec les journaux.

  • userIdQuestion 1 : L'asynchronisme fait que le thread enfant perd la somme dans le thread parent traceId.
  • Question 2 : L'asynchronie fait que le thread enfant et le thread parent n'utilisent pas un objet Trace, c'est-à-dire que les parties 1 et 2 du journal ci-dessus sont divisées .

améliorer

Résoudre le problème ci-dessus est en fait très simple, il suffit de le gérer de manière asynchrone, de copier manuellement la valeur dans le threadlocal du thread parent vers le thread enfant et de l'effacer après utilisation .

pseudo-code

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

Le pseudo-code ci-dessus est le code de base pour résoudre le problème, puis j'ai encapsulé cette logique dans EasyAdminMDCThreadPoolExecutor.java .

Les utilisateurs n'ont qu'à modifier le pool de threads précédent, l'exemple de code est le suivant.

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

L'effet log à ce moment est le suivant

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  // 这里是被修复处

Adresse complète du code : https://gitee.com/lakernote/easy-admin

Je suppose que tu aimes

Origine blog.csdn.net/abu935009066/article/details/130175669
conseillé
Classement