0%
Distributed Tracing avec Sleuth et Zipkin

Distributed Tracing avec Sleuth et Zipkin

Le suivi des requêtes distribuées

10-15 min

Distributed Tracing avec Sleuth et Zipkin

Dans ce chapitre, nous allons explorer l’implémentation du tracing distribué avec Spring Cloud Sleuth et Zipkin. Nous verrons comment suivre et analyser les requêtes à travers notre système de microservices.

1. Configuration de Base

Dépendances

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>

Configuration de base

# application.yml
spring:
  application:
    name: product-service
  sleuth:
    otel:
      config:
        trace-id-ratio-based: 1.0
    zipkin:
      base-url: http://localhost:9411
    otel:
      exporter:
        zipkin:
          endpoint: http://localhost:9411/api/v2/spans

2. Configuration de Zipkin

Démarrage de Zipkin

docker run -d -p 9411:9411 openzipkin/zipkin

Configuration avancée

spring:
  sleuth:
    otel:
      exporter:
        zipkin:
          endpoint: http://localhost:9411/api/v2/spans
          sender:
            type: web
            timeout: 10s
            connect-timeout: 5s
            read-timeout: 10s

3. Instrumentation des Services

Configuration des spans

@Configuration
public class TracingConfig {
    
    @Bean
    public TracingFilter tracingFilter(Tracer tracer) {
        return new TracingFilter(tracer);
    }
}

Filtre de tracing

@Component
public class TracingFilter implements Filter {
    
    private final Tracer tracer;
    
    public TracingFilter(Tracer tracer) {
        this.tracer = tracer;
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        Span span = tracer.nextSpan().name("http-request");
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            chain.doFilter(request, response);
        } finally {
            span.finish();
        }
    }
}

4. Intégration avec OpenTelemetry

Configuration OpenTelemetry

spring:
  sleuth:
    otel:
      config:
        trace-id-ratio-based: 1.0
      exporter:
        otlp:
          endpoint: http://localhost:4317
      propagator:
        type: b3

Instrumentation personnalisée

@Component
public class CustomTracer {
    
    private final Tracer tracer;
    
    public CustomTracer(Tracer tracer) {
        this.tracer = tracer;
    }
    
    public <T> T trace(String name, Supplier<T> operation) {
        Span span = tracer.nextSpan().name(name);
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            return operation.get();
        } finally {
            span.finish();
        }
    }
}

5. Intégration avec les Clients HTTP

Configuration Feign

@Configuration
public class FeignConfig {
    
    @Bean
    public RequestInterceptor requestInterceptor(Tracer tracer) {
        return requestTemplate -> {
            Span currentSpan = tracer.currentSpan();
            if (currentSpan != null) {
                requestTemplate.header("X-Trace-ID", currentSpan.context().traceId());
                requestTemplate.header("X-Span-ID", currentSpan.context().spanId());
            }
            return requestTemplate;
        };
    }
}

Configuration WebClient

@Configuration
public class WebClientConfig {
    
    @Bean
    public WebClient webClient(Tracer tracer) {
        return WebClient.builder()
            .filter((request, next) -> {
                Span currentSpan = tracer.currentSpan();
                if (currentSpan != null) {
                    request.headers()
                        .add("X-Trace-ID", currentSpan.context().traceId())
                        .add("X-Span-ID", currentSpan.context().spanId());
                }
                return next.exchange(request);
            })
            .build();
    }
}

6. Métriques et Monitoring

Configuration Actuator

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always

Métriques personnalisées

@Component
public class TracingMetrics {
    
    private final MeterRegistry registry;
    
    public TracingMetrics(MeterRegistry registry) {
        this.registry = registry;
    }
    
    public void recordSpan(String name, long duration) {
        registry.timer("tracing.spans", "name", name)
               .record(duration, TimeUnit.MILLISECONDS);
    }
}

7. Visualisation et Analyse

Configuration de l’UI

spring:
  sleuth:
    ui:
      enabled: true
      base-url: http://localhost:9411

Requêtes personnalisées

@RestController
@RequestMapping("/api/traces")
public class TraceController {
    
    private final ZipkinQueryApi queryApi;
    
    public TraceController(ZipkinQueryApi queryApi) {
        this.queryApi = queryApi;
    }
    
    @GetMapping("/search")
    public List<Span> searchTraces(
            @RequestParam String serviceName,
            @RequestParam long startTime,
            @RequestParam long endTime) {
        return queryApi.getTraces(serviceName, startTime, endTime);
    }
}

8. Exercices pratiques

  1. Configuration du tracing

    • Configurez Sleuth et Zipkin
    • Instrumentez vos services
    • Testez le tracing des requêtes
  2. Intégration avec les clients

    • Configurez le tracing pour Feign
    • Configurez le tracing pour WebClient
    • Testez les appels entre services
  3. Analyse des traces

    • Visualisez les traces dans Zipkin
    • Analysez les latences
    • Identifiez les goulots d’étranglement

Conclusion

Dans ce chapitre, nous avons exploré :

  • La configuration de base de Sleuth et Zipkin
  • L’instrumentation des services
  • L’intégration avec OpenTelemetry
  • L’intégration avec les clients HTTP
  • Les métriques et le monitoring
  • La visualisation des traces

Le tracing distribué permet :

  • Le suivi des requêtes à travers le système
  • L’identification des problèmes de performance
  • L’analyse des dépendances entre services
  • Le debugging des problèmes distribués

Dans le prochain chapitre, nous explorerons le Monitoring avec Prometheus et Grafana.

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !