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
-
Configuration du tracing
- Configurez Sleuth et Zipkin
- Instrumentez vos services
- Testez le tracing des requêtes
-
Intégration avec les clients
- Configurez le tracing pour Feign
- Configurez le tracing pour WebClient
- Testez les appels entre services
-
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