分布式链路追踪Brave集成

wen java案例 1

本文目录导读:

分布式链路追踪Brave集成

  1. Brave分布式链路追踪集成指南
  2. 基础依赖配置
  3. 核心配置实现
  4. 常用组件集成
  5. 自定义Span创建
  6. 自定义标签与注解
  7. 性能优化与最佳实践
  8. 完整配置示例
  9. 验证与调试

Brave分布式链路追踪集成指南

Brave是一个Java库,用于实现分布式追踪,它实现了OpenZipkin的API规范,下面是完整的集成指南:

基础依赖配置

Maven依赖

<!-- Brave核心库 -->
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>5.13.9</version>
</dependency>
<!-- 自动配置Spring集成 -->
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-spring-beans</artifactId>
    <version>5.13.9</version>
</dependency>
<!-- HTTP集成 -->
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-http</artifactId>
    <version>5.13.9</version>
</dependency>
<!-- Servlet集成 -->
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-servlet</artifactId>
    <version>5.13.9</version>
</dependency>
<!-- Spring Web集成 -->
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-spring-web</artifactId>
    <version>5.13.9</version>
</dependency>
<!-- 数据传输 -->
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-okhttp3</artifactId>
    <version>2.16.3</version>
</dependency>
<!-- Kafka传输(可选) -->
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-kafka</artifactId>
    <version>2.16.3</version>
</dependency>

核心配置实现

1 基础配置类

import brave.Tracing;
import brave.http.HttpTracing;
import brave.propagation.CurrentTraceContext;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.okhttp3.OkHttpSender;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BraveTracingConfig {
    @Bean
    public Tracing tracing() {
        return Tracing.newBuilder()
            .localServiceName("your-service-name")
            .spanReporter(spanReporter())
            .sampler(Sampler.ALWAYS_SAMPLE) // 采样率配置
            .currentTraceContext(ThreadLocalCurrentTraceContext.create())
            .build();
    }
    @Bean
    public HttpTracing httpTracing(Tracing tracing) {
        return HttpTracing.create(tracing);
    }
    private AsyncReporter spanReporter() {
        OkHttpSender sender = OkHttpSender.create("http://localhost:9411/api/v2/spans");
        return AsyncReporter.create(sender);
    }
}

2 Spring Boot自动配置

# application.yml
brave:
  service-name: your-service-name
  zipkin:
    base-url: http://localhost:9411
  sampler:
    probability: 1.0 # 采样率:0~1,1表示100%采样

常用组件集成

1 SQL数据库集成

// Maven依赖
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-jdbc</artifactId>
    <version>5.13.9</version>
</dependency>
// 配置JdbcTracing
import brave.Span;
import brave.Tracing;
import brave.jdbc.JdbcTracing;
import javax.sql.DataSource;
@Bean
public DataSource dataSource(Tracing tracing) {
    // 普通数据源
    DataSource realDataSource = createDataSource();
    // 包装为追踪数据源
    JdbcTracing jdbcTracing = JdbcTracing.create(tracing);
    return jdbcTracing.wrap(realDataSource);
}

2 HTTP客户端集成

// OkHttp集成
import brave.okhttp3.TracingInterceptor;
import okhttp3.OkHttpClient;
@Bean
public OkHttpClient okHttpClient(HttpTracing httpTracing) {
    return new OkHttpClient.Builder()
        .addInterceptor(TracingInterceptor.create(httpTracing))
        .build();
}
// RestTemplate集成
import brave.spring.web.TracingClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
@Bean
public RestTemplate restTemplate(HttpTracing httpTracing) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setInterceptors(
        Collections.singletonList(
            TracingClientHttpRequestInterceptor.create(httpTracing)
        )
    );
    return restTemplate;
}

3 消息队列集成

// RabbitMQ集成
import brave.spring.rabbit.SpringRabbitTracing;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@Bean
public SpringRabbitTracing rabbitTracing(Tracing tracing) {
    return SpringRabbitTracing.create(tracing);
}
@Bean
public RabbitTemplate rabbitTemplate(SpringRabbitTracing rabbitTracing) {
    RabbitTemplate template = new RabbitTemplate();
    rabbitTracing.setTracing(template);
    return template;
}
// Kafka集成
import brave.kafka.clients.KafkaTracing;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
@Bean
public KafkaTracing kafkaTracing(Tracing tracing) {
    return KafkaTracing.create(tracing);
}
@Bean
public Producer<String, String> kafkaProducer(KafkaTracing tracing) {
    Producer<String, String> producer = createKafkaProducer();
    return tracing.producer(producer);
}

自定义Span创建

1 在业务代码中使用

import brave.Span;
import brave.Tracer;
import brave.Tracing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BusinessService {
    @Autowired
    private Tracing tracing;
    @Autowired
    private Tracer tracer;
    public void businessMethod(String orderId) {
        // 创建自定义Span
        Span span = tracer.nextSpan()
            .name("process-order")
            .tag("order.id", orderId)
            .start();
        try {
            // 执行业务逻辑
            processOrder(orderId);
            // 添加自定义注解
            span.annotate("order.processed");
        } catch (Exception e) {
            span.error(e);
            throw e;
        } finally {
            span.finish();
        }
    }
    private void processOrder(String orderId) {
        // 嵌套Span示例
        Span subSpan = tracer.nextSpan()
            .name("validate-order")
            .tag("order.id", orderId)
            .start();
        try {
            // 子任务逻辑
            Thread.sleep(100);
        } finally {
            subSpan.finish();
        }
    }
}

2 上下文传播

import brave.propagation.CurrentTraceContext;
import brave.propagation.TraceContext;
@Service
public class ContextPropagationService {
    @Autowired
    private Tracing tracing;
    public void executeAsync(Runnable task) {
        // 获取当前上下文
        TraceContext context = tracing.currentTraceContext().get();
        // 在新线程中传递上下文
        executorService.submit(() -> {
            try (CurrentTraceContext.Scope scope = 
                    tracing.currentTraceContext().newScope(context)) {
                task.run();
            }
        });
    }
}

自定义标签与注解

1 添加业务标签

import brave.Span;
import brave.Tracer;
@Service
public class TracingTagService {
    @Autowired
    private Tracer tracer;
    public void addCustomTags(String userId, String operation) {
        Span span = tracer.currentSpan();
        if (span != null) {
            span.tag("user.id", userId);
            span.tag("operation.type", operation);
            span.tag("environment", System.getProperty("spring.profiles.active"));
        }
    }
}

2 错误追踪

import brave.Span;
import brave.Tracer;
@Component
public class ErrorTracingAspect {
    @Autowired
    private Tracer tracer;
    @Around("@annotation(org.springframework.web.bind.annotation.ExceptionHandler)")
    public Object traceException(ProceedingJoinPoint pjp) throws Throwable {
        try {
            return pjp.proceed();
        } catch (Exception e) {
            Span span = tracer.currentSpan();
            if (span != null) {
                span.error(e);
                span.tag("error.code", getErrorCode(e));
                span.tag("error.type", e.getClass().getName());
            }
            throw e;
        }
    }
}

性能优化与最佳实践

1 采样策略配置

import brave.sampler.RateLimitingSampler;
import brave.sampler.Sampler;
@Bean
public Sampler sampler() {
    // 每秒限制100个span
    return RateLimitingSampler.create(100);
    // 或者按比例采样
    // return Sampler.create(0.1f); // 10%采样率
}

2 Span优化

// 避免过多标签
Span span = tracer.nextSpan()
    .name("api-request")
    .tag("endpoint", "users") // 不要用动态URL
    .tag("method", "GET")
    .start();
// 使用注解代替大量标签
span.annotate("cache.miss");
span.annotate("db.query");

完整配置示例

import brave.Tracing;
import brave.http.HttpTracing;
import brave.propagation.CurrentTraceContext;
import brave.propagation.ThreadLocalCurrentTraceContext;
import brave.sampler.Sampler;
import brave.spring.web.TracingClientHttpRequestInterceptor;
import brave.spring.webmvc.SpanCustomizingHandlerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class FullBraveConfig implements WebMvcConfigurer {
    @Bean
    public Tracing tracing() {
        return Tracing.newBuilder()
            .localServiceName("user-service")
            .spanReporter(AsyncReporter.create(
                OkHttpSender.create("http://zipkin:9411/api/v2/spans")))
            .sampler(Sampler.ALWAYS_SAMPLE)
            .currentTraceContext(ThreadLocalCurrentTraceContext.create())
            .build();
    }
    @Bean
    public HttpTracing httpTracing(Tracing tracing) {
        return HttpTracing.create(tracing);
    }
    @Bean
    public RestTemplate restTemplate(HttpTracing httpTracing) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(
            List.of(TracingClientHttpRequestInterceptor.create(httpTracing))
        );
        return restTemplate;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 自动为所有Controller添加追踪
        registry.addInterceptor(SpanCustomizingHandlerInterceptor.create());
    }
}

验证与调试

1 日志配置

logging:
  level:
    brave: DEBUG
    zipkin: DEBUG

2 测试配置

@TestConfiguration
public class TestTracingConfig {
    @Bean
    public Tracing tracing() {
        return Tracing.newBuilder()
            .localServiceName("test-service")
            .spanReporter(span -> {
                // 打印到控制台
                System.out.println("Span: " + span);
            })
            .build();
    }
}

这个集成指南涵盖了Brave的主要功能,你可以根据实际需求选择合适的组件进行集成,分布式追踪的目的是帮助你理解系统行为,而不是增加不必要的开销,合理配置采样率非常重要。

抱歉,评论功能暂时关闭!