Le traçage distribué est important pour obtenir des informations et de l'observabilité dans une architecture de microservices à plusieurs niveaux. 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 Stackdriver 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. Stackdriver Trace peut également générer des rapports sur la répartition de la latence et détecter automatiquement les régressions de performances.
Vous disposez de deux options pour utiliser Stackdriver Trace à partir d'une application Spring Boot :
- Utilisez un proxy Zipkin Stackdriver Trace et configurez simplement Spring Cloud Sleuth pour qu'il utilise ce proxy comme point de terminaison Zipkin.
- 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 à Stackdriver 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 Stackdriver 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 ?
Comment évalueriez-vous votre expérience de création d'applications Web HTML/CSS ?
Quel est votre niveau d'expérience avec les services Google Cloud Platform ?
Configuration de l'environnement au rythme de chacun
Si vous ne possédez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform (console.cloud.google.com) et créez un projet :
Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID
tout au long de cet atelier de programmation.
Vous devez ensuite activer la facturation dans la console Cloud pour pouvoir utiliser les ressources Google Cloud.
Suivre cet atelier de programmation ne devrait pas vous coûter plus d'un euro. Cependant, cela peut s'avérer plus coûteux si vous décidez d'utiliser davantage de ressources ou si vous n'interrompez pas les ressources (voir la section "Effectuer un nettoyage" à la fin du présent document).
Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un essai sans frais avec 300$de crédits.
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 Google Cloud Shell
Depuis la console GCP, cliquez sur l'icône Cloud Shell de la barre d'outils située dans l'angle supérieur droit :
Cliquez ensuite sur "Démarrer Cloud Shell" :
Le provisionnement de l'environnement et la connexion ne devraient pas prendre plus de quelques minutes :
Cette machine virtuelle contient tous les outils de développement nécessaires. Elle intègre 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 dans un simple navigateur ou sur votre Chromebook Google.
Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est déjà défini avec votre PROJECT_ID.
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: - <myaccount>@<mydomain>.com (active)
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].
Une fois l'environnement 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 dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
-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!";
}
}
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 Aperçu sur le Web dans la barre d'outils Cloud Shell, puis choisissez Prévisualiser sur le port 8080.
Après un court délai, le résultat devrait s'afficher :
Dans Cloud Shell, vous devriez également voir les messages de journaux avec l'ID de trace et l'ID de portée :
Activer l'API Stackdriver Trace
Pour utiliser Stackdriver Trace afin de stocker vos données de trace, vous devez d'abord activer l'API Stackdriver Trace. Pour activer l'API, accédez à Services d'API → Bibliothèque.
Recherchez Stackdriver Trace.
Cliquez sur Stackdriver Trace API, puis sur Enable si elle n'est pas déjà activée.
Configurer les identifiants par défaut de l'application
Pour cet atelier, vous devrez configurer une identifiants par défaut de l'application. Ces identifiants seront automatiquement récupérés 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.
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 Stackdriver Trace.
Ajoutez la dépendance Spring Cloud GCP Trace :
pom.xml
<project>
...
<dependencies>
...
<!-- Add Stackdriver Trace Starter -->
<dependency>
<groupId>org.springframework.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 nous voyons les données de trace, et ignorez 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 par lot 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 à Stackdriver → Trace → Liste de traces.
En haut de l'écran, réduisez la période à une heure. Par défaut, l'actualisation automatique est activée. Ainsi, à mesure que les données de trace arrivent, elles devraient s'afficher dans la console.
Les données de trace devraient s'afficher au bout de 30 secondes environ.
Cliquez sur le point bleu pour afficher les détails de la trace :
C'était assez simple, non ?
Ouvrez une nouvelle session Cloud Shell en cliquant sur l'icône + :
Dans la nouvelle session, créez la deuxième application Spring Boot :
$ curl https://start.spring.io/starter.tgz -d packaging=jar \
-d dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
-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 Stackdriver Trace starter -->
<dependency>
<groupId>org.springframework.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 -Dserver.port=8081
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 l'aperçu sur le Web :
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run
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 Stackdriver Trace, vous devriez voir la deuxième trace :
Vous pouvez cliquer sur le nouveau point bleu pour afficher les détails de la trace :
Vous pouvez également cliquer sur n'importe quel segment de ce diagramme pour afficher ses détails.
Lorsque vous utilisez Stackdriver Trace comme stockage des données de trace, Stackdriver Trace peut utiliser les données pour générer un rapport sur la répartition de la latence. Vous aurez besoin de plus de 100 traces pour générer un rapport comme celui-ci :
De plus, Stackdriver Trace peut détecter automatiquement la régression des performances du même service sur deux périodes différentes dans Rapport d'analyse.
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 Stackdriver Trace.
Vous avez appris à créer votre première application Web App Engine.
En savoir plus
- Stackdriver Trace : https://cloud.google.com/trace/
- Projet Spring sur GCP : http://cloud.spring.io/spring-cloud-gcp/
- Dépôt GitHub Spring sur GCP : https://github.com/spring-cloud/spring-cloud-gcp
- Java sur Google Cloud Platform : https://cloud.google.com/java/
Licence
Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.