Traçage distribué avec Spring Cloud Sleuth et Cloud Trace

1. Présentation

Le traçage distribué est important pour obtenir des insights et de l'observabilité dans une architecture de microservices multicouche. Lorsque vous avez enchaîné des appels de service à service, du service A au service B, puis au service C, il est important de comprendre que les appels ont réussi et de connaître la latence à chaque étape.

Dans Spring Boot, vous pouvez utiliser Spring Cloud Sleuth pour ajouter facilement l'instrumentation de traçage distribué à votre application. Par défaut, il peut transférer les données de trace vers Zipkin.

Google Cloud Platform propose Cloud Trace, un service géré qui vous permet de stocker des données de trace sans avoir à gérer votre propre instance Zipkin ni votre propre stockage. Cloud Trace peut également générer des rapports sur la distribution de la latence et détecter automatiquement les régressions de performances.

Vous disposez de deux options pour utiliser Cloud Trace à partir d'une application Spring Boot :

  1. Utilisez un proxy Zipkin Stackdriver Trace et configurez simplement Spring Cloud Sleuth pour qu'il utilise ce proxy comme point de terminaison Zipkin.
  2. Vous pouvez également utiliser Spring Cloud GCP Trace, qui s'intègre de manière fluide à Spring Cloud Sleuth et transfère les données de trace directement à Cloud Trace.

Dans cet atelier de programmation, vous allez apprendre à créer une application Spring Boot et à utiliser Spring Cloud GCP Trace pour le traçage distribué.

Points abordés

  • Découvrez comment créer une application Java Spring Boot et configurer Cloud Trace.

Prérequis

  • Un projet Google Cloud Platform
  • Un navigateur tel que Chrome ou Firefox
  • Bonne connaissance des éditeurs de texte Linux standards tels que Vim, EMACs ou Nano

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Comment évalueriez-vous votre expérience de création d'applications Web HTML/CSS ?

Débutant Intermédiaire Expert

Quel est votre niveau d'expérience avec les services Google Cloud Platform ?

Débutant Intermédiaire Expert

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pourrez toujours le modifier.
  • L'ID du projet est unique parmi tous les projets Google Cloud et non modifiable une fois défini. La console Cloud génère automatiquement une chaîne unique (en général, vous n'y accordez d'importance particulière). Dans la plupart des ateliers de programmation, vous devrez indiquer l'ID de votre projet (généralement identifié par PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre de manière aléatoire. Vous pouvez également en spécifier un et voir s'il est disponible. Après cette étape, l'ID n'est plus modifiable et restera donc le même pour toute la durée du projet.
  • Pour information, il existe une troisième valeur (le numéro de projet) que certaines API utilisent. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour désactiver les ressources et éviter ainsi que des frais ne vous soient facturés après ce tutoriel, vous pouvez supprimer le projet ou les ressources que vous avez créées. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300 $.

Google Cloud Shell

Bien que vous puissiez commander Google Cloud et Kubernetes à distance depuis votre ordinateur portable, cet atelier de programmation utilisera Google Cloud Shell, un environnement de ligne de commande fonctionnant dans le cloud.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire s'affiche pour vous expliquer de quoi il s'agit. Si cet écran s'est affiché, cliquez sur Continuer.

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier de programmation dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est défini avec votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet :
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Créer un service REST Spring Boot

Une fois Cloud Shell lancé, vous pouvez utiliser la ligne de commande pour générer une application Spring Boot avec Spring Initializr :

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-one | tar -xzvf - \
  && cd trace-service-one

Créez un contrôleur REST en ajoutant une classe :

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class WorkController {
  Random r = new Random();

  public void meeting() {
    try {
      log.info("meeting...");
      // Delay for random number of milliseconds.
      Thread.sleep(r.nextInt(500));
    } catch (InterruptedException e) {
    }
  }

  @GetMapping("/")
  public String work() {
    // What is work? Meetings!
    // When you hit this URL, it'll call meetings() 5 times.
    // Each time will have a random delay.
    log.info("starting to work");
    for (int i = 0; i < 5; i++) {
      this.meeting();
    }
    log.info("finished!");
    return "finished work!";
  }
}

Assurez-vous d'avoir la bonne version de la JVM pour l'application :

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Vous pouvez démarrer l'application Spring Boot normalement avec le plug-in Spring Boot. Ignorons les tests pour cet atelier :

$ ./mvnw -DskipTests spring-boot:run

Une fois l'application démarrée, cliquez sur l'icône Web Preview (Aperçu sur le Web) 3a9b40fafa650b2b.png dans la barre d'outils Cloud Shell, puis choisissez Preview on port 8080 (Prévisualiser sur le port 8080).

3aca52f76c6c22a3.png

Après un court instant, le résultat devrait s'afficher :

6793a3339447cbb5.png

Dans Cloud Shell, vous devriez également voir les messages de journaux avec l'ID de trace et l'ID de portée :

18d597c388de1ba.png

4. Utiliser Cloud Trace

Activer l'API Cloud Trace

Vous devez d'abord activer l'API Cloud Trace avant d'utiliser Cloud Trace pour stocker vos données de trace. Pour activer l'API, exécutez la commande suivante :

$ gcloud services enable cloudtrace.googleapis.com

Configurer les identifiants par défaut de l'application

Pour cet atelier, vous devrez configurer une identifiant par défaut de l'application. Cette identifiant sera automatiquement récupéré par le starter Spring Cloud GCP Trace.

Tout d'abord, connectez-vous :

$ gcloud auth application-default login
You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used by Application Default
Credentials, so it is not necessary to use this command.
If you decide to proceed anyway, your user credentials may be visible
to others with access to this virtual machine. Are you sure you want
to authenticate with your personal account?
Do you want to continue (Y/n)? Y

Go to the following link in your browser:
    https://accounts.google.com/o/oauth2/auth...
Enter verification code: ...

Cliquez sur le lien pour ouvrir un nouvel onglet de navigateur, puis cliquez sur Autoriser.

85f500de6f5dc0a8.png

Ensuite, copiez et collez le code de validation dans Cloud Shell, puis appuyez sur Entrée. Vous devriez obtenir le résultat suivant :

Credentials saved to file: [/tmp/tmp.jm9bnQ4R9Q/application_default_credentials.json]
These credentials will be used by any library that requests
Application Default Credentials.

Ajouter Spring Cloud GCP Trace

Dans ce service, nous avons déjà utilisé Spring Cloud Sleuth pour le traçage. Ajoutons le starter Spring Cloud GCP Trace pour transférer les données vers Cloud Trace.

Ajoutez la dépendance Spring Cloud GCP Trace :

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace Starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

Par défaut, Spring Cloud Sleuth n'échantillonne pas toutes les requêtes. Pour faciliter nos tests, augmentez le taux d'échantillonnage à 100 % dans application.properties afin de vous assurer que les données de trace s'affichent. Ignorez également certaines URL qui ne nous intéressent pas :

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

Exécutez à nouveau l'application et utilisez l'aperçu sur le Web de Cloud Shell pour l'afficher :

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run

Par défaut, Spring Cloud GCP Trace regroupe les données de trace et les envoie toutes les 10 secondes, ou lorsqu'un nombre minimal de données de trace est reçu. Cette option est configurable. Pour en savoir plus, consultez la documentation de référence sur Spring Cloud GCP Trace.

Envoyez une requête au service :

$ curl localhost:8080

Dans la console Cloud, accédez à Opérations > Trace > Liste de traces.

be48cb0f99b5f7c2.png

En haut de l'écran, réduisez la période à une heure. Par défaut, l'option Rechargement automatique est activée. Ainsi, à mesure que les données de trace arrivent, elles devraient s'afficher dans la console.

3522eef823df39d8.png

Les données de trace devraient s'afficher au bout de 30 secondes environ.

9628f6e1d2e75b05.png

Cliquez sur le point bleu pour afficher les détails de la trace :

ba9051a8d4f3e725.png

C'était assez simple, non ?

5. Créer une deuxième application Web Spring Boot

Ouvrez une nouvelle session Cloud Shell en cliquant sur l'icône + :

9799bee5fea95aa6.png

Dans la nouvelle session, créez la deuxième application Spring Boot :

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-two | tar -xzvf - \
  && cd trace-service-two

Créez un contrôleur REST en ajoutant une classe :

src/main/java/com/example/demo/MeetingController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class MeetingController {
  Random r = new Random();

  @GetMapping("/meet")
  public String meeting() {
    try {
      log.info("meeting...");
      Thread.sleep(r.nextInt(500 - 20 + 1) + 20);
    } catch (InterruptedException e) {
    }
    return "finished meeting";
  }
}

Ajouter Spring Cloud GCP Trace à pom.xml

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

Configurez Sleuth pour qu'il échantillonne 100 % des requêtes :

src/main/resources/application.properties

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

Enfin, vous pouvez démarrer l'application Spring Boot sur le port 8081 avec le plug-in Spring Boot :

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"

6. Mettre à jour le premier service pour consommer le deuxième service

Pendant que trace-service-two est en cours d'exécution, revenez à la première fenêtre de session Cloud Shell et modifiez trace-service-one.

Commencez par initialiser un nouveau bean RestTemplate :

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

...

import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {
        @Bean
        public RestTemplate restTemplate() {
                return new RestTemplate();
        }
        
        public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
        }
}

Dans WorkController.meeting(), appelez le service Meet.

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

...
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;

@RestController
@Slf4j
public class WorkController {
  @Autowired
  RestTemplate restTemplate;

  public void meeting() {
    String result = restTemplate.getForObject("http://localhost:8081/meet", String.class);
    log.info(result);
  }

  ...
}

Redémarrez le service et déclenchez le point de terminaison à partir de la ligne de commande :

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`

# The '&' places the process in the background. Bring it back to the foreground with 'fg'.
$ ./mvnw -DskipTests spring-boot:run &

$ curl localhost:8080

Dans les deux fenêtres de session, vous devriez voir les messages de journal, avec l'ID de trace propagé d'un service à l'autre.

Dans la liste des traces de Cloud Trace, vous devriez voir la deuxième trace :

13490977f1638702.png

Vous pouvez cliquer sur le nouveau point bleu pour afficher les détails de la trace :

ca69ef9cdd13d4aa.png

Vous pouvez également cliquer sur n'importe quel span de ce diagramme pour afficher ses détails.

7. Rapport sur la distribution et les performances de la latence

Lorsque vous utilisez Cloud Trace comme stockage des données de trace, il peut utiliser les données pour générer un rapport sur la distribution de la latence. Pour créer un rapport comme celui-ci, vous devez disposer de plus de 100 traces :

c8713f3d9e51dc25.png

Vous pouvez exécuter ces 100 premières requêtes et plus à l'aide de hey, qui est préinstallé sur Cloud Shell.

$ hey localhost:8080 -n 150

De plus, Cloud Trace peut détecter automatiquement la régression des performances du même service sur deux périodes différentes dans Rapport d'analyse.

8. Résumé

Dans cet atelier, vous avez créé deux services simples, ajouté le traçage distribué avec Spring Cloud Sleuth et utilisé Spring Cloud GCP pour transférer les informations de trace vers Cloud Trace.

9. Félicitations !

Vous avez appris à créer votre première application Web App Engine.

En savoir plus

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.