zipkin对于线程池已经提供了很完善的方式处理,例如:
CurrentTraceContext currentTraceContext = MDCCurrentTraceContext.create();
currentTraceContext.wrap(()->{System.out.println("hi");});
ExecutorService executorService = currentTraceContext.executorService(Executors.newFixedThreadPool(1));
executorService.execute(()-> System.out.println("hi"));
但上述实现仅对于Thread与ExecutorService有效,而对java 8的并行流则无能为力。例如:
String[] hi = new String[]{"hi"};
Arrays.stream(hi).parallel().forEach(System.out::println);
这里主要是由于java 8的并行流使用的是ForkJoinPool,系统启动时,会默认初始化一个commonPool。因而加入zipkin的关键也在于如何修改commonPool的默认属性。
为此,感谢文章给指明了前进的方向 。解决方案如下:
static {
System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory",
ZipkinForkJoinWorkerThreadFactory.class.getName());
}
public class ZipkinForkJoinWorkerThread extends ForkJoinWorkerThread {
private final TraceContext invocationContext = ZipkinContext.getCurrentTraceContext().get();
public ZipkinForkJoinWorkerThread(ForkJoinPool pool) {
super(pool);
}
@Override
public void run() {
try (CurrentTraceContext.Scope scope = ZipkinContext.getCurrentTraceContext().maybeScope(invocationContext)) {
super.run();
}
}
}
public class ZipkinForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new ZipkinForkJoinWorkerThread(pool);
}
}