繁体   English   中英

在多线程 Java 服务器中使用跟踪

[英]Using tracing in a multithreaded Java server

我在多线程应用程序中使用跟踪时遇到问题。

背景:

在我的 SpringBoot 应用程序中,我有一个 function“服务”调用另一个 function“innerService”,我想用自己的跨度跟踪每个 function。 我通过以下方式使用 Jaeger 实现 OpenTracing:

AppConfig.java:

@Bean
public static JaegerTracer getTracer() {
    io.jaegertracing.Configuration.SamplerConfiguration samplerConfig = io.jaegertracing.Configuration.SamplerConfiguration.fromEnv().withType("const").withParam(1);
    io.jaegertracing.Configuration.ReporterConfiguration reporterConfig = io.jaegertracing.Configuration.ReporterConfiguration.fromEnv().withLogSpans(true);
    io.jaegertracing.Configuration config = new io.jaegertracing.Configuration("myService").withSampler(samplerConfig).withReporter(reporterConfig);
    return config.getTracer();
}

然后我在我的一个应用程序服务中使用它:

@GrpcService
public class ServiceA extends ServiceAGrpc.ServiceAImplBase {
     private final Tracer tracer;

     @Autowired
     public ServiceA(Tracer tracer) {
         this.tracer = tracer;
}

@Override
public void service(Request request, StreamObserver<ResultGrpc> responseObserver) {
    Span span = startSpanInScope(this.tracer, "service");
    ...
    innerService();
    ...
    span.finish();
}

返回跨度的 function:

public static Span startSpanInScope(Tracer tracer, String spanName) {
    if (tracer == null) {
        return null;
    }
    Span span = tracer.buildSpan(spanName).start();
    Scope scope = tracer.scopeManager().activate(span);
    return span;
}

当向服务发送单个请求时,一切似乎都很好,跨度出现在另一个之中:

在此处输入图像描述

但是,当我使用多个线程一次发送多个请求时,跨度会相互干扰: 在此处输入图像描述

我猜这是因为每当一个跨度开始时,它就会成为当前活动跨度的子级,即使这个跨度来自另一个线程。 我不明白为什么,因为我读到 ScopeManager 默认是 ThreadLocal object。

任何人都可以提出解决方案吗? 我希望每个线程都有一个单独的跟踪,这将显示“服务”和“innerService”作为其子项的跨度。

你也必须关闭你的 scope ( scope.close() ) 而不仅仅是跨度,这可能是你的跟踪连续的原因。 关闭 scope 会自动完成跨度。 此外,您可以在单个命令中直接创建一个跨度作为活动跨度: Scope scope = tracer.buildSpan(spanName).startActive(true) 这样,您就不必手动调用scopeManager

由于Scope class 实现了AutoClosable接口,您可以使用 try-resource 块来防止丢失 scope 关闭:

try (Scope scope = this.tracer.buildSpan("service").startActive(true)) {
    innerService();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM