introduction
Dans cet article, nous allons explorer comment implémenter le traçage distribué à l’aide de Jaeger et comment visualiser les traces à l’aide de l’interface utilisateur Jaeger.
Jaeger est un mécanisme de traçage distribué open source qui permet de suivre les demandes dans les systèmes distribués. Il est basé sur la spécification OpenTracing et fait partie de la Cloud Native Computing Foundation (CNCF).
J’ai expliqué certains concepts clés du traçage dans mon article précédent « Traçage distribué avec Spring Cloud Sleuth ».
Avec cela, regardons un peu de code.
Implémentation du traçage Jaeger
Créons une application à partir de https://start.spring.io avec une seule dépendance de « Spring Web ».
Une fois que vous avez généré et téléchargé le code, nous ajouterons la dépendance Jaeger suivante au fichier pom qui aidera à générer et à propager les traces entre les services.
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
<version>3.3.1</version>
</dependency>
Avec cela, ajoutons un contrôleur avec quelques chemins.
@RestController
@RequestMapping("/service")
public class Controller {
private static final Logger logger = LoggerFactory.getLogger(Controller.class);
private RestTemplate restTemplate;
@Value("${spring.application.name}")
private String applicationName;
public Controller(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/path1")
public ResponseEntity path1() {
logger.info("Incoming request at {} for request /path1 ", applicationName);
String response = restTemplate.getForObject("http://localhost:8090/service/path2", String.class);
return ResponseEntity.ok("response from /path1 + " + response);
}
@GetMapping("/path2")
public ResponseEntity path2() {
logger.info("Incoming request at {} at /path2", applicationName);
return ResponseEntity.ok("response from /path2 ");
}
}
Ici, nous avons deux points de terminaison : /path1
et /path2
. L’idée ici est d’utiliser deux instances de la même application telles que /path1
appels /path2
d’un autre service à un port fixe 8090.
Pour que les spans soient connectés au même identifiant de trace, nous devons créer un bean RestTemplate pour permettre à Jaeger d’inclure un intercepteur. Cela permet ensuite d’ajouter des traces à la demande sortante, ce qui aidera à tracer l’intégralité de la demande.
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
Ceci fait, démarrons un serveur Jaeger localement à l’aide de Docker. Pour cela, j’ai créé un fichier Docker Compose avec les mappages de ports.
version: "3.3"
services:
jaeger-allinone:
image: jaegertracing/all-in-one:1.25
ports:
- 6831:6831/udp
- 6832:6832/udp
- 16686:16686
- 14268:14268
Nous pouvons communiquer avec Jaeger via UDP ou TCP. Après avoir démarré l’image Docker en utilisant docker-compose up
, nous pouvons accéder à l’interface utilisateur en utilisant l’URL http://localhost:16686/.
Ajoutons maintenant quelques propriétés pour permettre à l’application d’envoyer les traces au serveur Jaeger. Nous communiquerons via TCP, alors assurez-vous que nous envoyons les traces sur l’autre port TCP, c’est-à-dire 14268
opentracing:
jaeger:
http-sender:
url: http://localhost:14268/api/traces
Commençons « Serveur 1 » avec la commande ci-dessous.
java -jar
target/Distributed-Service-0.0.1-SNAPSHOT.jar
--spring.application.name=Service-1
--server.port=8080
Ensuite, sur un autre terminal, exécutez une nouvelle instance de la même application que « Service 2 » comme suit
java -jar
target/Distributed-Service-0.0.1-SNAPSHOT.jar
--spring.application.name=Service-2
--server.port=8090
Une fois l’application lancée, appelez « Service 1 » au /path1
comme suit
curl -i http://localhost:8080/service/path1
Regardons les journaux de « Service 1 ».
INFO 69938 --- [nio-8080-exec-1] i.j.internal.reporters.LoggingReporter : Span reported: ed70bbaa2bd5b42f:c7c94163fc95fc1e:ed70bbaa2bd5b42f:1 - GET
Le tracé est du format [Root Span ID, Current Span ID, Parent Span ID]. Dans ce cas, étant donné que « Service 1 » est le service d’origine, l’ID d’étendue parent ed70bbaa2bd5b42f
est également l’ID d’étendue racine.
Maintenant, regardons les journaux de « Service 2 ».
INFO 69885 --- [nio-8090-exec-1] i.j.internal.reporters.LoggingReporter : Span reported: ed70bbaa2bd5b42f:e9060cb1d5336c55:c7c94163fc95fc1e:1 - path2
Ici, nous voyons que la valeur du milieu est l’ID de span actuel et l’ID de span parent (c’est-à-dire la troisième valeur c7c94163fc95fc1e
) est l’ID d’étendue de « Service 1 ».
Maintenant, si vous ouvrez l’interface utilisateur, vous verrez ce qui suit :

Lorsque nous creusons plus profondément, nous voyons plus de détails sur chacune des travées.

Ici, l’identifiant de l’étendue racine ed70bbaa2bd5b42f
s’étend sur l’ensemble de la demande. Les deux autres ID d’étendue font référence à des services individuels.
Conclusion
Aujourd’hui, nous avons exploré comment intégrer Jaeger, qui est basé sur OpenTracing avec une application Spring Boot. Vous pouvez toujours en savoir plus sur les spécifications d’OpenTracing ici. De plus, la documentation de la bibliothèque pour l’utilisation de Spring Cloud Jaeger est ici.
J’ai téléchargé le code sur GitHub.
Vous pouvez en savoir plus sur le traçage distribué à l’aide de Zipkin dans mon article précédent ici.
Je continue d’explorer et d’apprendre de nouvelles choses. Si vous voulez connaître les dernières tendances et améliorer vos compétences en développement de logiciels, suivez-moi sur Twitter.
Prendre plaisir!!