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

1. Présentation

Le traçage distribué est important pour obtenir des insights et une observabilité pour une architecture de microservices à plusieurs niveaux. Lorsque vous enchaînez des appels de service à un service, du service A au service B en passant par le service C, il est important de comprendre que les appels ont abouti ainsi que 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 transmettre les données de trace à Zipkin.

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

Pour utiliser Cloud Trace à partir d'une application Spring Boot, deux options s'offrent à vous:

  1. Utilisez un proxy Zipkin de Stackdriver Trace et configurez simplement Spring Cloud Sleuth pour utiliser ce proxy comme point de terminaison Zipkin.
  2. Vous pouvez également utiliser Spring Cloud GCP Trace, qui s'intègre parfaitement à Spring Cloud Sleuth et transmet 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

  • 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 en matière 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 ?

<ph type="x-smartling-placeholder"></ph> 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 la 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 Google Cloud et Kubernetes puissent être utilisés à distance depuis votre ordinateur portable, nous allons utiliser Google Cloud Shell dans cet atelier de programmation, un environnement de ligne de commande exécuté 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 vous explique de quoi il s'agit. Si un écran intermédiaire vous s'est présenté, cliquez sur Continue (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 dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur 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 nouvelle 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!";
  }
}

Vérifiez que vous disposez de la bonne version de 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 quelques instants, vous devriez obtenir le résultat suivant:

6793a3339447cbb5.png

Dans Cloud Shell, vous devriez également voir les messages de journal avec l'ID de trace et l'ID de délai:

18d597c388de1ba.png

4. Utiliser Cloud Trace

Activer l'API Cloud Trace

Vous devez activer l'API Cloud Trace avant de stocker vos données de trace à l'aide de Cloud 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 devez configurer des identifiants d'application par défaut. Cet identifiant sera automatiquement récupéré par le déclencheur 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 du navigateur, puis 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 déclencheur 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 les tests, augmentez le taux d'échantillonnage à 100% dans application.properties pour vous assurer que les données de trace s'affichent, et ignorez certaines URL qui ne vous 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 afficher l'application:

$ 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. Ceci 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érationsTraceListe de traces.

be48cb0f99b5f7c2.png

En haut de l'écran, réduisez la période à une heure. Par défaut, l'actualisation automatique est activée. Ainsi, lorsque les données de trace arrivent, elles doivent apparaître dans la console.

3522eef823df39d8.png

Les données de trace devraient s'afficher dans un délai d'environ 30 secondes.

9628f6e1d2e75b05.png

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

ba9051a8d4f3e725.png

C'était assez simple !

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 Trace GCP au fichier 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 échantillonner 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 utiliser 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 de réunion.

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 à un autre.

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

13490977f1638702.png

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

ca69ef9cdd13d4aa.png

Vous pouvez également cliquer sur n'importe quel segment de ce schéma pour afficher ses détails.

7. Répartition de la latence et Rapport sur les performances

Lorsque vous utilisez Cloud Trace comme stockage des données de trace, Cloud Trace peut s'en servir pour créer un rapport sur la répartition de la latence. Vous avez besoin de plus de 100 traces pour créer le rapport comme suit:

c8713f3d9e51dc25.png

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

$ hey localhost:8080 -n 150

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

8. Résumé

Dans cet atelier, vous avez créé deux services simples et ajouté un traçage distribué avec Spring Cloud Sleuth. Vous avez également utilisé Spring Cloud GCP pour transmettre les informations de trace à Cloud Trace.

9. Félicitations !

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

En savoir plus

Licence

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