Contactez-nous

Suivi distribué avec Micrometer Tracing (anciennement Spring Cloud Sleuth) et Zipkin/Jaeger

Apprenez à implémenter le suivi distribué dans vos microservices Spring Boot en utilisant Micrometer Tracing et à exporter les traces vers Zipkin ou Jaeger pour l'analyse.

Le besoin de suivi dans les systèmes distribués

Dans une architecture microservices, une simple requête utilisateur peut traverser plusieurs services indépendants avant qu'une réponse ne soit formulée. Si une erreur survient ou si la requête est anormalement lente, identifier la cause racine devient un véritable défi. Les logs individuels de chaque service sont souvent insuffisants car il est difficile de les corréler pour reconstituer le parcours complet de la requête initiale.

Le suivi distribué (Distributed Tracing) est une technique essentielle pour l'observabilité des systèmes distribués. Son objectif est de suivre le cycle de vie complet d'une requête à mesure qu'elle se propage à travers les différents services, en collectant des données sur le temps passé à chaque étape et les dépendances entre les services. Cela permet de visualiser le flux, de diagnostiquer les problèmes de latence et de comprendre les interactions complexes au sein de l'architecture.

Des outils comme Zipkin et Jaeger sont des systèmes de back-end conçus pour collecter, stocker, interroger et visualiser ces données de traçage distribué, offrant une interface utilisateur pour explorer les traces et analyser les performances.

Micrometer Tracing : le standard Spring Boot pour le traçage

Historiquement, Spring Cloud Sleuth était le projet dédié à l'ajout automatique d'informations de traçage (Trace IDs, Span IDs) aux requêtes et aux logs dans les applications Spring Cloud. Cependant, depuis Spring Boot 3, cette fonctionnalité a été intégrée et généralisée sous l'égide du projet Micrometer, via Micrometer Tracing.

Micrometer Tracing agit comme une façade d'instrumentation pour le traçage distribué, similaire à ce que Micrometer fait pour les métriques. Il fournit une API commune et s'appuie sur des implémentations de traçage réelles sous-jacentes. Les principales implémentations (bridges) supportées sont :

  • Brave : Une bibliothèque de traçage Java populaire, l'implémentation derrière Zipkin et celle historiquement utilisée par Sleuth.
  • OpenTelemetry (OTel) SDK : L'implémentation basée sur OpenTelemetry, un standard émergent de la Cloud Native Computing Foundation (CNCF) pour l'instrumentation et la collecte de données de télémétrie (traces, métriques, logs).

L'avantage est que votre application interagit avec l'API Micrometer Tracing, et vous pouvez choisir le bridge et l'exportateur vers le backend (Zipkin, Jaeger, etc.) via la configuration et les dépendances, sans changer votre code métier. Spring Boot auto-configure l'instrumentation pour de nombreux composants (contrôleurs web, clients REST, messagerie, tâches planifiées, etc.) pour créer et propager automatiquement les spans.

Concepts clés : Traces, Spans et Propagation

Le fonctionnement du suivi distribué repose sur quelques concepts fondamentaux :

  • Trace : Représente l'ensemble du parcours d'une requête à travers tous les services impliqués. Une trace est identifiée par un Trace ID unique.
  • Span : Représente une unité de travail spécifique au sein d'une trace (par exemple, un appel HTTP entrant, une requête SQL, un appel à une autre méthode). Chaque span a un Span ID unique et est associé au Trace ID global.
  • Contexte de Trace (Trace Context) : Contient au minimum le Trace ID et le Span ID du span parent.
  • Propagation : Lorsque le service A appelle le service B, le contexte de trace (Trace ID, Span ID de l'appelant A) est transmis (propagé) au service B, généralement via des en-têtes HTTP standardisés (comme B3 Propagation ou W3C Trace Context). Le service B crée alors un nouveau span pour son travail, en référençant le Span ID de A comme son parent.
  • Instrumentation : Le processus (souvent automatique grâce à Micrometer Tracing) d'ajout de code pour démarrer/arrêter des spans, et pour injecter/extraire le contexte de trace lors des communications inter-services.
  • MDC (Mapped Diagnostic Context) : Micrometer Tracing intègre souvent les Trace ID et Span ID dans le MDC du logger, permettant de les inclure facilement dans les logs pour une corrélation aisée entre traces et logs.

Mise en place : Dépendances et configuration de base

Pour activer le suivi distribué et l'export vers un backend, vous avez généralement besoin des dépendances suivantes :

  1. spring-boot-starter-actuator : Fournit les dépendances de base de Micrometer.
  2. Un bridge Micrometer Tracing : Par exemple, micrometer-tracing-bridge-brave (pour Zipkin notamment) ou micrometer-tracing-bridge-otel.
  3. Un exportateur vers votre backend : Par exemple, micrometer-registry-zipkin (qui dépend de Brave) ou des dépendances spécifiques à l'exportateur OpenTelemetry (comme opentelemetry-exporter-zipkin, opentelemetry-exporter-jaeger, ou opentelemetry-exporter-otlp pour le protocole OTLP générique).

Exemple de dépendances Maven pour exporter vers Zipkin via Brave :


    org.springframework.boot
    spring-boot-starter-actuator



    io.micrometer
    micrometer-tracing-bridge-brave



    io.zipkin.reporter2
    zipkin-reporter-brave



    io.zipkin.reporter2
    zipkin-sender-okhttp3

Note : Auparavant, micrometer-registry-zipkin existait mais est maintenant déprécié au profit des dépendances directes `zipkin-reporter`. La configuration est clé.

Configuration de base dans application.properties :

# Nom du service tel qu'il apparaîtra dans les traces
spring.application.name=mon-service-utilisateur

# Configuration du traçage
management.tracing.sampling.probability=1.0 # Echantillonner 100% des requêtes (pour démo/dev)
# En production, utiliser une valeur plus faible (ex: 0.1 pour 10%)

# Configuration de l'export vers Zipkin (si vous utilisez le bridge Brave)
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
# management.zipkin.tracing.sender.type=web # web, kafka, rabbit, etc. (web par défaut)

# Configuration de l'export vers Jaeger via OTLP (si vous utilisez le bridge OTel et l'exportateur OTLP)
# management.otlp.tracing.endpoint=http://localhost:4318/v1/traces

# Inclure traceId et spanId dans le pattern de log (via MDC)
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]

La configuration pour Jaeger peut varier selon l'exportateur OTel choisi (gRPC, HTTP/protobuf, HTTP/json). La configuration OTLP est la plus courante.

Zipkin et Jaeger : Collecte et visualisation

Zipkin :

  • Un système de traçage distribué open-source, initialement développé par Twitter.
  • Il fournit une interface utilisateur web simple pour rechercher et visualiser les traces sous forme de diagramme de Gantt (waterfall), montrant la durée et la relation parent-enfant des spans.
  • Il offre également une vue des dépendances entre services.
  • Le serveur Zipkin peut être facilement lancé via Docker : docker run -d -p 9411:9411 openzipkin/zipkin.
  • L'exportateur Spring Boot envoie les données de span collectées (via Brave) à l'endpoint configuré (/api/v2/spans).

Jaeger :

  • Un autre système de traçage distribué open-source, initié par Uber et maintenant un projet gradué de la CNCF.
  • Il est souvent utilisé avec OpenTelemetry et supporte nativement le modèle de données OTel.
  • Il offre également une interface web pour la visualisation des traces (similaire à Zipkin mais avec quelques fonctionnalités différentes), l'analyse des dépendances et des métriques basées sur les traces.
  • Peut être lancé via Docker avec une image tout-en-un pour le développement : docker run -d --name jaeger -p 16686:16686 -p 4317:4317 -p 4318:4318 jaegertracing/all-in-one:latest (expose l'UI sur 16686 et les endpoints OTLP gRPC sur 4317 et HTTP sur 4318).
  • L'exportateur OTel dans Spring Boot envoie les données au endpoint OTLP configuré.

Une fois l'application Spring Boot démarrée avec la configuration d'export appropriée et le backend (Zipkin ou Jaeger) lancé, effectuez quelques requêtes qui traversent vos microservices. Vous devriez alors pouvoir retrouver et visualiser ces traces complètes dans l'interface utilisateur du backend choisi.

Explorer une trace : Analyse et débogage

L'interface utilisateur de Zipkin ou Jaeger présente généralement une trace sous forme de diagramme de Gantt (Waterfall). Chaque barre horizontale représente un span.

  • Hiérarchie : L'indentation montre la relation parent-enfant entre les spans. Le span racine est généralement l'appel HTTP initial reçu par le premier service (ou la passerelle API).
  • Durée : La longueur de la barre indique la durée de ce span.
  • Timing : La position horizontale indique quand le span a commencé et s'est terminé par rapport au début de la trace.
  • Service : Chaque span est associé au service qui l'a exécuté (basé sur spring.application.name).
  • Détails du Span : En cliquant sur un span, vous pouvez voir des informations supplémentaires (tags/attributs) comme l'URL HTTP appelée, la méthode HTTP, le statut de la réponse, les requêtes SQL, les messages d'erreur, etc.

Cette vue permet rapidement :

  • D'identifier le chemin exact suivi par une requête.
  • De repérer les spans qui prennent le plus de temps (goulots d'étranglement).
  • De voir où une erreur s'est produite dans la chaîne d'appels.
  • De comprendre les dépendances entre les services pour une requête donnée.

De plus, ces outils fournissent souvent une vue agrégée des dépendances entre services, générée à partir de l'analyse de nombreuses traces.

Conclusion : L'observabilité grâce au suivi distribué

Le suivi distribué, facilité dans l'écosystème Spring par Micrometer Tracing (succédant à Spring Cloud Sleuth), et visualisé grâce à des backends comme Zipkin ou Jaeger, est un pilier essentiel de l'observabilité des architectures microservices.

Il transforme la complexité des interactions distribuées en une vue compréhensible, permettant aux équipes de développement et d'exploitation de diagnostiquer plus rapidement les problèmes, d'optimiser les performances et de mieux comprendre le comportement global de leur système. L'intégration transparente offerte par Spring Boot rend l'adoption de ces pratiques beaucoup plus accessible, en automatisant une grande partie de l'instrumentation et de la propagation du contexte.