À propos de cet atelier de programmation
1. Présentation
Le traçage distribué est important pour obtenir des insights et une observabilité dans une architecture de microservices à plusieurs niveaux. Lorsque vous avez effectué des appels de service en service, du service A au service B en passant par le service C, il est important de comprendre que les appels ont bien été effectués et la latence à chaque étape.
Dans Spring Boot, vous pouvez utiliser Spring Cloud Sleuth pour ajouter facilement l'instrumentation de traçage distribuée à 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 les données de trace sans gérer votre propre instance Zipkin ni votre espace de stockage. Stackdriver Trace peut aussi générer des rapports de distribution de latence et détecter automatiquement les régressions de performances.
Deux options s'offrent à vous pour utiliser Stackdriver Trace à partir d'une application Spring Boot:
- Utiliser un proxy Stackdriver Trace Zipkin et configurer simplement Spring Cloud Sleuth pour utiliser ce proxy comme point de terminaison Zipkin
- Vous pouvez également utiliser Spring Cloud Trace, qui s'intègre parfaitement à 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 Trace pour le traçage distribué.
Points abordés
- 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 niveau en matière de création d'applications Web HTML/CSS ?
Quel est votre niveau d'expérience avec les services Google Cloud Platform ?
2. Prérequis
Configuration de l'environnement au rythme de chacun
Si vous n'avez 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 Cloud Console afin d'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 offert de 300 $.
Google Cloud Shell
Vous pouvez utiliser Google Cloud et Kubernetes à distance depuis votre ordinateur portable. Dans cet atelier de programmation, nous utiliserons 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.
En principe, une fois que vous êtes connecté à Cloud Shell, vous êtes authentifié, et le projet est défini sur 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].
3. Créer un service REST Spring Boot
Après le lancement de Cloud Shell, 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 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. Ignorez les tests de 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 sélectionnez Preview on port 8080 (Prévisualiser sur le port 8080).
Après quelques instants, vous devriez voir le résultat suivant:
Dans Cloud Shell, vous devriez également voir les messages de journal avec l'ID de trace et l'ID de délai:
4. Utiliser Stackdriver Trace
Activer l'API Stackdriver Trace
Vous devez activer l'API Stackdriver Trace avant de pouvoir stocker les données de trace à l'aide de Stackdriver Trace. Pour activer l'API, accédez à Services d'API → Bibliothèque.
Recherchez Stackdriver Trace.
Cliquez sur Stackdriver Trace API (API Stackdriver Trace), puis sur Enable (Activer) si elle n'est pas déjà activée.
Configuration des identifiants par défaut de l'application
Pour cet atelier, vous devrez configurer un identifiant d'application par défaut. Ces identifiants seront automatiquement récupérés par Spring Cloud GCP Trace Starter.
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 Allow (Autoriser).
Ensuite, copiez et collez le code de validation dans Cloud Shell, puis appuyez sur Entrée. Vous devriez voir les éléments suivants :
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 une trace Spring Cloud GCP
Dans ce service, nous avons déjà utilisé Spring Cloud Sleuth pour le traçage. Ajoutons le déclencheur de trace Spring Cloud GCP pour transférer les données à Stackdriver Trace.
Ajoutez la dépendance Trace Cloud dans GCP:
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 le test, augmentez le taux d'échantillonnage à 100% dans application.properties
afin de voir 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 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 regroupe les données de trace et les envoie une fois toutes les 10 secondes ou lorsqu'un nombre minimal de données de trace est reçu. Cette configuration est configurable. Pour en savoir plus, consultez la documentation de référence de Spring Cloud Trace.
Envoyez une requête au service:
$ curl localhost:8080
Dans Cloud Console, accédez à Stackdriver → Trace → Trace list (Liste de traces).
En haut, réduisez la période à une heure. L'actualisation automatique est activée par défaut. Les données de trace devraient donc apparaître dans la console.
Les données de trace devraient s'afficher dans environ 30 secondes.
Cliquez sur le point bleu bleu pour afficher les détails de la trace:
C'est assez simple !
5. Créer une deuxième application Web Spring Boot
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 Trace au fichier 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
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 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 à un autre.
Dans Stackdriver Trace, la deuxième trace est indiquée:
Cliquez sur le nouveau point bleu pour consulter les détails de la trace:
Vous pouvez également cliquer sur une période de ce diagramme pour afficher le détail de celle-ci.
7. Répartition de la latence et rapport sur les performances
Lorsque vous utilisez Stackdriver Trace comme stockage des données de trace, il peut générer un rapport de distribution de la latence à l'aide des données. Vous aurez besoin de plus de 100 traces pour créer le rapport de la manière suivante:
En outre, Stackdriver Trace peut détecter automatiquement la régression des performances du 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 et utilisé Spring Cloud GCP pour transférer les informations de trace à Stackdriver Trace.
9. Félicitations !
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/
- Spring sur le dépôt GitHub de 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.