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子类。
posted on 2023-03-29 11:53  zhengbiyu  阅读(187)  评论(0编辑  收藏  举报