关于springcloud组件sleuth在项目中遇到的问题
背景
项目中使用JUC的线程池打印日志时,在大数据收集后,Kibana读的recordId都是重复的,这是现象.
原因
再多线程下sleuth的日志组件生成的recordid就是重复的,这个他们组件提供了TraceableExecutorService来处理这个问题.
解决方案
虽然提供了TraceableExecutorService来解决重复ID的问题,但是这个类的源码如下,看了源码就会发现其实他实现了ExecutorService的方法外在没有提供其他的方法,比如ThreadPoolExecutor内会提供查询线程池内的活跃线程数(getActiveCount方法),这让我们使用起来很不方便.所以看各个不同场景的选择了,由于我们并没有使用线程池的任务队列(是因为我们需要对队列进行监控,线程池内的队列没有redis队列好监控,所以我们选择使用redis队列),我们需要保证队列监控的稳定性所以就接受了recordid重读的事情.
总结
TraceableExecutorService实际上只是在ExecutorService的基础上维护了一个ExecutorService.所有的方法也是调用这个ExecutorService来执行的.其他的就是一些日志收集的组件了,比如(Tracing,SpanNamer.....).
附
1 /* 2 * Copyright 2013-2018 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.springframework.cloud.sleuth.instrument.async; 17 18 import java.util.ArrayList; 19 import java.util.Collection; 20 import java.util.List; 21 import java.util.concurrent.Callable; 22 import java.util.concurrent.ExecutionException; 23 import java.util.concurrent.ExecutorService; 24 import java.util.concurrent.Future; 25 import java.util.concurrent.TimeUnit; 26 import java.util.concurrent.TimeoutException; 27 28 import brave.Tracing; 29 import org.springframework.beans.factory.BeanFactory; 30 import org.springframework.cloud.sleuth.SpanNamer; 31 32 /** 33 * A decorator class for {@link ExecutorService} to support tracing in Executors 34 * 35 * @author Gaurav Rai Mazra 36 * @since 1.0.0 37 */ 38 public class TraceableExecutorService implements ExecutorService { 39 final ExecutorService delegate; 40 private final String spanName; 41 Tracing tracing; 42 SpanNamer spanNamer; 43 BeanFactory beanFactory; 44 45 public TraceableExecutorService(BeanFactory beanFactory, final ExecutorService delegate) { 46 this(beanFactory, delegate, null); 47 } 48 49 public TraceableExecutorService(BeanFactory beanFactory, final ExecutorService delegate, String spanName) { 50 this.delegate = delegate; 51 this.beanFactory = beanFactory; 52 this.spanName = spanName; 53 } 54 55 @Override 56 public void execute(Runnable command) { 57 final Runnable r = new TraceRunnable(tracing(), spanNamer(), command, this.spanName); 58 this.delegate.execute(r); 59 } 60 61 @Override 62 public void shutdown() { 63 this.delegate.shutdown(); 64 } 65 66 @Override 67 public List<Runnable> shutdownNow() { 68 return this.delegate.shutdownNow(); 69 } 70 71 @Override 72 public boolean isShutdown() { 73 return this.delegate.isShutdown(); 74 } 75 76 @Override 77 public boolean isTerminated() { 78 return this.delegate.isTerminated(); 79 } 80 81 @Override 82 public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { 83 return this.delegate.awaitTermination(timeout, unit); 84 } 85 86 @Override 87 public <T> Future<T> submit(Callable<T> task) { 88 Callable<T> c = new TraceCallable<>(tracing(), spanNamer(), task, this.spanName); 89 return this.delegate.submit(c); 90 } 91 92 @Override 93 public <T> Future<T> submit(Runnable task, T result) { 94 Runnable r = new TraceRunnable(tracing(), spanNamer(), task, this.spanName); 95 return this.delegate.submit(r, result); 96 } 97 98 @Override 99 public Future<?> submit(Runnable task) { 100 Runnable r = new TraceRunnable(tracing(), spanNamer(), task, this.spanName); 101 return this.delegate.submit(r); 102 } 103 104 @Override 105 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { 106 return this.delegate.invokeAll(wrapCallableCollection(tasks)); 107 } 108 109 @Override 110 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) 111 throws InterruptedException { 112 return this.delegate.invokeAll(wrapCallableCollection(tasks), timeout, unit); 113 } 114 115 @Override 116 public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { 117 return this.delegate.invokeAny(wrapCallableCollection(tasks)); 118 } 119 120 @Override 121 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) 122 throws InterruptedException, ExecutionException, TimeoutException { 123 return this.delegate.invokeAny(wrapCallableCollection(tasks), timeout, unit); 124 } 125 126 private <T> Collection<? extends Callable<T>> wrapCallableCollection(Collection<? extends Callable<T>> tasks) { 127 List<Callable<T>> ts = new ArrayList<>(); 128 for (Callable<T> task : tasks) { 129 if (!(task instanceof TraceCallable)) { 130 ts.add(new TraceCallable<>(tracing(), spanNamer(), task, this.spanName)); 131 } 132 } 133 return ts; 134 } 135 136 Tracing tracing() { 137 if (this.tracing == null && this.beanFactory != null) { 138 this.tracing = this.beanFactory.getBean(Tracing.class); 139 } 140 return this.tracing; 141 } 142 143 SpanNamer spanNamer() { 144 if (this.spanNamer == null && this.beanFactory != null) { 145 this.spanNamer = this.beanFactory.getBean(SpanNamer.class); 146 } 147 return this.spanNamer; 148 } 149 }

浙公网安备 33010602011771号