Tracciamento distribuito con Spring Cloud Sleuth e Cloud Trace

1. Panoramica

Il tracciamento distribuito è importante per ottenere insight e osservabilità per un'architettura di microservizi multi-livello. Quando hai concatenato le chiamate tra servizi, dal servizio A al servizio B e al servizio C, è importante comprendere che le chiamate sono andate a buon fine e anche la latenza in ogni passaggio.

In Spring Boot, puoi utilizzare Spring Cloud Sleuth per aggiungere senza problemi la strumentazione di tracciamento distribuito alla tua applicazione. Per impostazione predefinita, può inoltrare i dati di traccia a Zipkin.

Nella piattaforma Google Cloud è disponibile Cloud Trace, un servizio gestito che consente di archiviare i dati di traccia senza dover gestire l'istanza o l'archiviazione di Zipkin. Cloud Trace può inoltre generare report sulla distribuzione della latenza e rilevare automaticamente le regressioni delle prestazioni.

Sono disponibili due opzioni per utilizzare Cloud Trace da un'applicazione Spring Boot:

  1. Utilizza un proxy Zipkin di Stackdriver Trace e configura semplicemente Spring Cloud Sleuth in modo che utilizzi questo proxy come endpoint Zipkin
  2. In alternativa, utilizza Spring Cloud GCP Trace, che si integra perfettamente con Spring Cloud Sleuth e inoltra i dati di traccia direttamente a Cloud Trace.

In questo codelab, imparerai a creare una nuova applicazione Spring Boot e a utilizzare Spring Cloud GCP Trace per il tracciamento distribuito.

Cosa imparerai a fare

  • Creare un'applicazione Java Spring Boot e configurare Cloud Trace.

Che cosa ti serve

  • Un progetto Google Cloud
  • Un browser, ad esempio Chrome o Firefox
  • Familiarità con gli editor di testo standard di Linux, ad esempio Vim, EMAC o Nano.

Come utilizzerai questo tutorial?

Solo lettura Leggilo e completa gli esercizi

Come valuteresti la tua esperienza nello sviluppo di app web HTML/CSS?

Principiante Livello intermedio Eccellente

Come giudichi la tua esperienza di utilizzo dei servizi della piattaforma Google Cloud?

Principiante Livello intermedio Eccellente

2. Configurazione e requisiti

Configurazione dell'ambiente da seguire in modo autonomo

  1. Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Il Nome progetto è il nome visualizzato dei partecipanti del progetto. Si tratta di una stringa di caratteri non utilizzata dalle API di Google. Puoi sempre aggiornarla.
  • L'ID progetto è univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca. di solito non ti importa cosa sia. Nella maggior parte dei codelab, dovrai fare riferimento al tuo ID progetto (in genere identificato come PROJECT_ID). Se l'ID generato non ti soddisfa, potresti generarne un altro casuale. In alternativa, puoi provarne una personalizzata per verificare se è disponibile. Non può essere modificato dopo questo passaggio e rimane per tutta la durata del progetto.
  • Per informazione, c'è un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
  1. Successivamente, dovrai abilitare la fatturazione nella console Cloud per utilizzare risorse/API Cloud. L'esecuzione di questo codelab non ha alcun costo. Per arrestare le risorse ed evitare di incorrere in fatturazione dopo questo tutorial, puoi eliminare le risorse che hai creato o eliminare il progetto. I nuovi utenti di Google Cloud sono idonei al programma prova senza costi di 300$.

Google Cloud Shell

Mentre Google Cloud e Kubernetes possono essere gestiti da remoto dal tuo laptop, in questo codelab utilizzeremo Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.

Attiva Cloud Shell

  1. Dalla console Cloud, fai clic su Attiva Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Se è la prima volta che avvii Cloud Shell, ti verrà mostrata una schermata intermedia che descrive di cosa si tratta. Se ti è stata presentata una schermata intermedia, fai clic su Continua.

9c92662c6a846a5c.png

Il provisioning e la connessione a Cloud Shell dovrebbero richiedere solo qualche istante.

9f0e51b578fecce5.png

Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.

Una volta stabilita la connessione a Cloud Shell, dovresti vedere che hai eseguito l'autenticazione e che il progetto è impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per confermare che il comando gcloud è a conoscenza del tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Crea un nuovo servizio REST Spring Boot

Dopo l'avvio di Cloud Shell, puoi utilizzare la riga di comando per generare una nuova applicazione Spring Boot con 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

Crea un nuovo controller REST aggiungendo una nuova 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!";
  }
}

Assicurati di avere la versione JVM corretta per l'applicazione:

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

Puoi avviare l'applicazione Spring Boot normalmente con il plug-in Spring Boot. Saltiamo i test di questo lab:

$ ./mvnw -DskipTests spring-boot:run

Una volta avviata l'applicazione, fai clic sull'icona Anteprima web 3a9b40fafa650b2b.png nella barra degli strumenti di Cloud Shell e scegli Anteprima sulla porta 8080.

3aca52f76c6c22a3.png

Dopo una breve attesa, dovresti vedere il risultato:

6793a3339447cbb5.png

In Cloud Shell dovresti vedere anche i messaggi di log con ID traccia e ID intervallo:

18d597c388de1ba.png

4. Utilizzo di Cloud Trace

Abilita API Cloud Trace

Prima di utilizzare Cloud Trace per archiviare i dati di traccia, devi abilitare l'API Cloud Trace. Per abilitare l'API, esegui:

$ gcloud services enable cloudtrace.googleapis.com

Configura credenziale predefinita applicazione

Per questo lab dovrai configurare una credenziale predefinita dell'applicazione. Questa credenziale verrà acquisita automaticamente dal comando iniziale di Trace Spring Cloud Google Cloud.

Per prima cosa, accedi:

$ 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: ...

Fai clic sul link per aprire una nuova scheda del browser, quindi fai clic su Consenti

85f500de6f5dc0a8.png

Quindi, copia e incolla di nuovo il codice di verifica in Cloud Shell e premi Invio. Dovresti vedere:

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

Aggiungi traccia Spring Cloud Google Cloud

In questo servizio abbiamo già utilizzato Spring Cloud Sleuth per il tracciamento. Aggiungiamo il comando iniziale di Trace Cloud Google Cloud Spring per inoltrare i dati a Cloud Trace.

Aggiungi la dipendenza 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>

Per impostazione predefinita, Spring Cloud Sleuth non campiona ogni richiesta. Per semplificare i test, aumenta la frequenza di campionamento al 100% in application.properties per assicurarti di vedere i dati di traccia e per ignorare alcuni URL che non ci interessano:

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

Esegui di nuovo l'applicazione e utilizza l'anteprima web di Cloud Shell per visualizzarla:

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

Per impostazione predefinita, Spring Cloud GCP Trace raggruppa i dati di traccia in batch e li invia una volta ogni 10 secondi o quando viene ricevuto un numero minimo di dati di traccia. Questa opzione è configurabile e per ulteriori informazioni puoi consultare la documentazione di riferimento di Spring Cloud GCP Trace.

Per inviare una richiesta al servizio:

$ curl localhost:8080

Nella console Cloud, vai a OperazioniTraceElenco di tracce.

be48cb0f99b5f7c2.png

In alto, riduci l'intervallo di tempo a 1 ora. L'opzione Ricarica automaticamente è attiva per impostazione predefinita. Quando arrivano i dati di traccia, questi dovrebbero essere visualizzati nella console.

3522eef823df39d8.png

I dati di traccia dovrebbero essere visualizzati entro circa 30 secondi.

9628f6e1d2e75b05.png

Fai clic sul punto blu per visualizzare i dettagli della traccia:

ba9051a8d4f3e725.png

È stato semplicissimo.

5. Crea una seconda applicazione web Spring Boot

Apri una nuova sessione di Cloud Shell facendo clic sull'icona +:

9799bee5fea95aa6.png

Nella nuova sessione, crea la seconda applicazione 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

Crea un nuovo controller REST aggiungendo una nuova 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";
  }
}

Aggiungi Trace Cloud Cloud Spring a 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>

Configura Sleuth per campionare il 100% delle richieste:

src/main/resources/application.properties

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

Infine, puoi avviare l'applicazione Spring Boot sulla porta 8081 con il 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. Aggiorna il primo servizio per utilizzare il secondo servizio

Mentre è in esecuzione trace-service-two, torna alla prima finestra della sessione di Cloud Shell e apporta la modifica a trace-service-one.

Per prima cosa, inizializza un nuovo 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);
        }
}

In WorkController.meeting(), fai una chiamata al servizio 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);
  }

  ...
}

Avvia di nuovo il servizio e attiva l'endpoint dalla riga di comando:

$ 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

In entrambe le finestre della sessione, dovresti vedere i messaggi di log, con l'ID traccia propagato da un servizio a un altro.

Nell'elenco di tracce di Cloud Trace dovresti vedere la seconda traccia:

13490977f1638702.png

Puoi fare clic sul nuovo punto blu e visualizzare i dettagli della traccia:

ca69ef9cdd13d4aa.png

Puoi anche fare clic su un intervallo qualsiasi di questo diagramma per visualizzarne i dettagli.

7. Distribuzione della latenza e Report sul rendimento

Quando utilizzi Cloud Trace come spazio di archiviazione dei dati di traccia, Cloud Trace può utilizzare i dati per creare un report di distribuzione della latenza. Per creare un report come questo, sono necessarie più di 100 tracce:

c8713f3d9e51dc25.png

Puoi eseguire le prime oltre 100 richieste utilizzando hey, preinstallato su Cloud Shell.

$ hey localhost:8080 -n 150

Inoltre, Cloud Trace può rilevare automaticamente la regressione delle prestazioni dello stesso servizio in due diversi periodi di tempo in Analysis Report.

8. Riepilogo

In questo lab, hai creato due semplici servizi, aggiunto il tracciamento distribuito con Spring Cloud Sleuth e utilizzato Spring Cloud GCP per inoltrare le informazioni di traccia a Cloud Trace.

9. Complimenti!

Hai imparato a scrivere la tua prima applicazione web di App Engine.

Scopri di più

Licenza

Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.