Un des problèmes rencontrés dans une application basée sur l'architecture Microservices est la difficulté de débugger. En effet, chaque requête peut transiter par des dizaines de microservices avant d'aboutir.
Rien que dans notre application très basique, la récupération d'une liste de produits passe par ZUUL, puis par Microservice-produits, avant de refaire le chemin dans le sens inverse. À tout moment, cette requête peut rencontrer un problème. La question est : où chercher quand il y a un bug ? Comment voir le chemin qu'une requête a parcouru afin de détecter où le problème s'est déclenché ?
Eh bien, nous avons des outils très puissants qui répondent à ces problématiques.
Étape 1 : Nous avons besoin d'identifier de façon unique chaque requête pour pouvoir la tracer. L'outil que l'on va utiliser pour cela est Spring Sleuth. Il va donner un ID unique à chaque requête à travers nos microservices, de façon à pouvoir les suivre avec précision.
Étape 2 : Nous avons des requêtes marquées par des ID, mais comment les suivre concrètement ? Afficher dans la console chaque requête, puis plisser les yeux pour pouvoir distinguer d'où chacune vient et où elles partent ?
La solution est d'avoir un microservice à part, qui centralise et organise toutes les traces des requêtes qui passent à tous les niveaux de notre application. Nous allons donc utiliser Zipkin pour cette tâche.
Ajoutez Spring Sleuth aux microservices
Afin d'accomplir la première étape qui consiste à ajouter un ID unique à chaque requête transitant par nos microservices, nous allons les enrichir des dépendances Sleuth.
Faisons cela sur ZUUL pour commencer. Comme d'habitude, ajoutez le starter de Sleuth :
pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
N'oubliez pas d'actualiser Maven.
Nous devons maintenant configurer Sleuth afin de lui préciser quelles requêtes tracer. Pour cela, nous allons ajouter une classe de configuration.
Créez une classe SleuthConfig sous un package : configuration.
SleuthConfig.java
package com.mcommerce.zuulserver.configuration;
import brave.sampler.Sampler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SleuthConfig
{
public Sampler defaultSampler()
{
return Sampler.ALWAYS_SAMPLE;
}
}
Sampler.ALWAYS_SAMPLE
demande que toutes les requêtes soient marquées par des ID et soient exportables vers d'autres services comme Zipkin.
Faites la même opération pour ClientUI et Microservice-produits.
Afin de pouvoir vérifier que Sleuth fonctionne directement dans la console avant d'en arriver à Zipkin, affichez un message de log dans chaque service que traversera la requête.
Dans notre cas, nous allons appeler la page d'accueil de l'application. La requête passera alors par ClientUI -> ZUUL -> Microservice-produits.
Voici l'exemple d'un message de log dans ProductController.java :
Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
ApplicationPropertiesConfiguration appProperties;
// Affiche la liste de tous les produits disponibles
@GetMapping(value = "/Produits")
public List<Product> listeDesProduits()
{
List<Product> products = productDao.findAll();
if(products.isEmpty()) throw new ProductNotFoundException("Aucun produit n'est disponible à la vente");
List<Product> listeLimitee = products.subList(0, appProperties.getLimitDeProduits());
log.info("Récupération de la liste des produits");
return listeLimitee;
}
Très bien. Lancez tous les microservices et rendez-vous sur la page d'accueil de l'application.
Vous verrez ceci dans la console du client :
La phrase que nous avons loggée est précédée d'une liste entre crochets ajoutée par Sleuth :
INFO [microservice-clientui,80ae7a23f6c62de8,80ae7a23f6c62de8,true] 12648 --- [nio-8080-exec-2] c.clientui.controller.ClientController : Envoi requête vers microservice-produits
[microservice-clientui,80ae7a23f6c62de8,80ae7a23f6c62de8,true]
se compose de 4 éléments : [Nom de l'application, ID de traçage, ID du Span, Export (true/false)].
Cette série d'informations donne tous les éléments à connaître pour pouvoir suivre l'application à travers les différents microservices.
Nom de l'application : le nom fourni dans application.properties.
ID de traçage : ID unique pour identifier cette requête.
Span ID : un Span est une étape dans le trajet d'une requête. Chaque requête commence avec un ID et un Span ID identiques, mais à chaque étape, le Span ID change, alors que l'ID de traçage reste fixe. Dans notre cas, nous allons avoir un Span ID différent pour ZUUL et pour Microservice-produits.
Export : c'est la classe de configuration que nous avons ajoutée qui a fixé cette valeur à true. Elle permet de dire si cette requête est exportable vers Zipkin ou équivalent.
Vous avez donc ce log dans ZUUL :
Et ceci dans Microservice-produits :
Remarquez que l'ID de traçage reste le même (80ae7a23f6c62de8), alors que le Span ID change à chaque étape.
Ajoutez Zipkin
Depuis la version 2 de Spring Boot, le serveur Zipkin n'est plus inclus par défaut, et ne peut pas être ajouté facilement via un starter.
Nous allons donc télécharger Zipkin et le lancer comme un fichier JAR classique.
Une fois téléchargé, lancez-le via la commande :
java -jar /chemin/vers/zipkin-server-2.6.1-exec.jar
Assurez-vous d'avoir Java 8 ou au-dessus.
Une fois lancé, rendez-vous à l'URL http://localhost:9411 pour afficher la page d'accueil de Zipkin.
Ajoutez ensuite cette dépendance à tous les microservices :
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
Actualisez Maven et redémarrez le tout.
Rendez-vous sur Postman et exécutez plusieurs GET sur localhost:8080 afin de générer des requêtes que Sleuth va tracer et envoyer automatiquement à Zipkin.
Actualisez Zipkin. Vous devriez alors voir la liste des microservices par lesquels les requêtes ont transité dans la liste déroulante :
Cliquez sur une requête. Vous avez alors cette vue :
Vous voyez le cheminement de la requête dans l'ordre, en partant de Microservice-clientui, jusqu'à l'aboutissement dans Microservice-produits.
Cliquez sur la première requête, par exemple. Vous avez un tableau avec toutes les informations sur la requête et le contrôleur qui l'a traitée.
Maintenant que nous pouvons tracer nos requêtes nous allons utiliser un outil merveilleux qu’est Spring Actuator qui nous permet de visualiser plein de metrics sur nos applications.
En résumé
Zipkin sert à tracer les requêtes, que ce soit pour voir le temps d'exécution ou les directions.
Dans le prochain chapitre, vous allez apprendre à débugger votre application grâce à Spring Actuator