비동기 스레드 풀 시나리오에서 추적 기능을 향상시키기 위해 처음부터 개발 스캐폴딩 구축
머리말
다음 두 글은 이전에 작성한 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