如何避免 Sleuth Slf4J 集成的大量开销

How to avoid massive overhead of Sleuth Slf4J integration

在我们的Spring引导应用程序(2.0.4.RELEASE)中,我们使用Zipkin来集成分布式跟踪。

当以 10% 的采样率手动创建集成时,意味着 @Configuration 像这样:

@Configuration
public class ZipkinConfiguration {
    @Value("${grpc.zipkin.endpoint:}")
    private String zipkinEndpoint;
    @Bean
    public SpanCustomizer currentSpanCustomizer(Tracing tracing) {
        return CurrentSpanCustomizer.create(tracing);
    }
    @Bean
    public Tracing tracing(@Value("${spring.application.name}") String serviceName) {
        return Tracing.newBuilder().localServiceName(serviceName).spanReporter(spanReporter()).build();
    }

    private Reporter<Span> spanReporter() {
        return AsyncReporter.create(sender());
    }

    private Sender sender() {
        return OkHttpSender.create(zipkinEndpoint);
    }
}

在每秒大约 10 个请求的情况下,我们的应用程序的 50 个百分位性能约为 19 毫秒,99.9 个百分位性能约为 90 毫秒。

集成 Sleuth 2.0 时。2.RELEASE 而不是 gradle 中的这样:

compile "org.springframework.cloud:spring-cloud-starter-sleuth:2.0.2.RELEASE"
compile "org.springframework.cloud:spring-cloud-sleuth-zipkin:2.0.2.RELEASE"

性能大幅下降至 49 毫秒的 p50 和 120 毫秒的 p999。

我尝试禁用 Sleuth 集成的不同部分(spring.sleuth.async.enabledspring.sleuth.reactor.enabled 等)。

禁用所有这些集成会使性能达到 p50:25 毫秒,p999:103 毫秒。 仅仅拥有 Sleuth 就会增加大约 15-25% 的开销。

事实证明,影响重大的一件事是将 spring.sleuth.log.slf4j.enabled 设置为 false。如果启用所有其他集成,但禁用此集成,则性能将保持在上述 Sleuth 开销范围内,但不会记录任何内容。

所以我的问题是: 有没有办法避免 Sleuth 的开销(与 "manual" 跟踪相比),尤其是 SLF4J 集成完成的开销?

如您所述,选项是禁用 Slf4j 集成。创建新的跨度/范围时,我们通过 Slf4j 将数据放入 MDC,不幸的是这需要时间。禁用它会保存它。