traceId实现
普通
内部拦截器,threadlocal变量set上下文context。
父子线程传递
InheritableThreadLocal
Thread内部为InheritableThreadLocal开辟了一个单独的ThreadLocalMap。在父线程创建一个子线程的时候,会检查这个ThreadLocalMap是否为空,不为空则会浅拷贝给子线程的ThreadLocalMap。
线程池场景传递
TransmittableThreadLocal,有个专门的TtlRunnable和TtlCallable包装类,用于读取原Thread的ThreadLocal对象及值并存于Runnable/Callable中,在执行run或者call方法的时候再将存于Runnable/Callable中的ThreadLocal对象和值读取出来,存入调用run或者call的线程中。
public void testAsync() { ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(executorService); String traceId = Tracer.startServer(); //父线程的traceId ThreadLocal<String> traceContext = new TransmittableThreadLocal<>(); traceContext.set(traceId); //存入TransmittableThreadLocal ttlExecutorService.submit(new Runnable() { @Override public void run() { //runnable执行中获取当前线程的traceId与父线程的traceId一致 String childTraceId = traceContext.get(); Assert.assertEquals(childTraceId, traceId); Tracer.startClient(traceId); Tracer.endClient(); } }); Tracer.endServer(); }
考虑到代码入侵,可以通过-javaagent:/xx/transmittable-thread-local.jar启动,对原生类进行字节码增强。提交的java.lang.Runnable类型的任务会被包装为TtlRunnable,提交的java.util.concurrent.Callable类型的任务会被包装为TtlCallable,实现了无入侵无感知地嵌入TTL的功能。
TtlExecutorTransformlet处理的类:ThreadPoolExecutor及其子类、ScheduledThreadPoolExecutor。
TtlForkJoinTransformlet处理的类:ForkJoinTask、ForkJoinPool 默认开启。
TtlTimerTaskTransformlet处理的类:仅处理TimeTask子类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构