单个线程
在单个线程的调用过程中,通过ThreadLocal来完成在整个线程执行过程中获取相同的Trace值,Zipkin也是通过定义了一个ThreadLocal local来实现处理的。
父子线程
在主线程中新建立一个子线程时使用ThreadLocal就无效了,因此Zipkin提供了如下定义方式,使用InheritableThreadLocal定义(可以参考博客Java 多线程:InheritableThreadLocal 实现原理)
static final InheritableThreadLocal INHERITABLE = new InheritableThreadLocal<>();
这样就是存在父子线程,在创建子线程的过程中会将父线程的值全部拷贝到子线程中,这样在子线程中依然可以获取到Trace值,因此如下面的代码追踪链路依然是完整的。
Zipkin类CurrentTraceContext给出对线程及线程池的的处理方法就是实现了Runnable重新实现了run方法,这样就解决了线程池的问题.
具体实现:查看CurrentTraceContext 类
1、使用CurrentTraceContext 创建CurrentTraceContext
CurrentTraceContext context=CurrentTraceContext.Default.create();
2、 ThreadPoolExecutor executorPool;
3、 executorPool.execute(context.wap(Runnable(){}));
具体参照CurrentTraceContext 中的wap
public Runnable wrap(Runnable task) {
final TraceContext invocationContext = get();
class CurrentTraceContextRunnable implements Runnable {
@Override public void run() {
try (Scope scope = maybeScope(invocationContext)) {
task.run();
}
}
}
return new CurrentTraceContextRunnable();
}