有哪个网站可以做ppt赚钱,易网拓营销型网站,网页设计实训总结三百字,天津市建设工程交易信息网在学习Zipkin分布式追踪系统中我们了解到Trace在整个调用链是一致的#xff0c;在web服务中可以通过在header设置Trace值在不同的服务中进行传递#xff0c;那样在一个服务内部不同的线程#xff0c;甚至是线程池中Zipkin是如何处理的#xff0c;接下来我们来了解学习一下。…在学习Zipkin分布式追踪系统中我们了解到Trace在整个调用链是一致的在web服务中可以通过在header设置Trace值在不同的服务中进行传递那样在一个服务内部不同的线程甚至是线程池中Zipkin是如何处理的接下来我们来了解学习一下。单个线程在单个线程的调用过程中我们一般都知道通过ThreadLocal来完成在整个线程执行过程中获取相同的Trace值Zipkin也是通过定义了一个ThreadLocal local来实现处理的。父子线程在主线程中新建立一个子线程时使用ThreadLocal就无效了因此Zipkin提供了如下定义方式使用InheritableThreadLocal定义(可以参考博客Java 多线程InheritableThreadLocal 实现原理)static final InheritableThreadLocal INHERITABLE new InheritableThreadLocal();这样就是存在父子线程在创建子线程的过程中会将父线程的值全部拷贝到子线程中这样在子线程中依然可以获取到Trace值因此如下面的代码追踪链路依然是完整的。RequestMapping(/start2)public String start(HttpServletRequest request1,HttpServletResponse response1) throws InterruptedException, IOException {Thread thread new Thread((new Runnable() {Overridepublic void run() {System.err.println(Thread.currentThread().hashCode());data restTemplate.getForObject(http://localhost:9090/foo, String.class);}}));thread.start();return data;}线程池在我们新创建一个线程然后将线程提交给线程池时由于线程池中线程执行的原理此时原线程中的ThreadLocal和InheritableThreadLocal都是无效的追踪Trace值因此会丢失导致整个调用链出现断路如下面代码。RequestMapping(/start2)public String start(HttpServletRequest request1,HttpServletResponse response1) throws InterruptedException, IOException {String data ;Thread thread new Thread((new Runnable() {Overridepublic void run() {System.err.println(Thread.currentThread().hashCode());data restTemplate.getForObject(http://localhost:9090/foo, String.class);}}));executor.execute(thread);Thread.sleep(10000);return data;}目前Zipkin类CurrentTraceContext给出对线程及线程池的的处理方法就是实现了Runnable重新实现了run方法这样就解决了线程池的问题当然不只提供了创建线程的方法还包括线程池和Callablepublic Runnable wrap(Runnable task) {//获取父线程中的Tracefinal TraceContext invocationContext get();class CurrentTraceContextRunnable implements Runnable {Override public void run() {//将父线程中的Trace复制到子线程中try (Scope scope maybeScope(invocationContext)) {task.run();}}}return new CurrentTraceContextRunnable();}public Scope maybeScope(Nullable TraceContext currentSpan) {TraceContext currentScope get();if (currentSpan null) {if (currentScope null) return Scope.NOOP;return newScope(null);}return currentSpan.equals(currentScope) ? Scope.NOOP : newScope(currentSpan);}public Executor executor(Executor delegate) {class CurrentTraceContextExecutor implements Executor {Override public void execute(Runnable task) {delegate.execute(CurrentTraceContext.this.wrap(task));}}return new CurrentTraceContextExecutor();}/*** Decorates the input such that the {link #get() current trace context} at the time a task is* scheduled is made current when the task is executed.*/public ExecutorService executorService(ExecutorService delegate) {class CurrentTraceContextExecutorService extends brave.internal.WrappingExecutorService {Override protected ExecutorService delegate() {return delegate;}Override protected Callable wrap(Callable task) {return CurrentTraceContext.this.wrap(task);}Override protected Runnable wrap(Runnable task) {return CurrentTraceContext.this.wrap(task);}}return new CurrentTraceContextExecutorService();}public Callable wrap(Callable task) {final TraceContext invocationContext get();class CurrentTraceContextCallable implements Callable {Override public C call() throws Exception {try (Scope scope maybeScope(invocationContext)) {return task.call();}}}return new CurrentTraceContextCallable();}