Verteiltes Tracing mit Spring Cloud Sleuth und Cloud Trace

1. Übersicht

Verteiltes Tracing ist wichtig, um Einblicke in eine mehrschichtige Mikrodienstarchitektur zu erhalten und sie zu beobachten. Wenn Sie Dienst-zu-Dienst-Aufrufe verketten, z. B. von Dienst A zu Dienst B zu Dienst C, ist es wichtig, dass Sie wissen, ob die Aufrufe erfolgreich waren und wie hoch die Latenz in jedem Schritt ist.

In Spring Boot können Sie Spring Cloud Sleuth verwenden, um Ihrer Anwendung nahtlos die Instrumentierung für verteiltes Tracing hinzuzufügen. Standardmäßig können die Trace-Daten an Zipkin weitergeleitet werden.

Google Cloud bietet Cloud Trace, einen verwalteten Dienst, mit dem Sie Tracedaten speichern können, ohne Ihre eigene Zipkin-Instanz oder Ihren eigenen Speicher verwalten zu müssen. Cloud Trace kann auch Berichte zur Latenzverteilung erstellen und Leistungsbeeinträchtigungen automatisch erkennen.

Sie haben zwei Möglichkeiten, Cloud Trace in einer Spring Boot-Anwendung zu verwenden:

  1. Verwenden Sie einen Stackdriver Trace Zipkin-Proxy und konfigurieren Sie Spring Cloud Sleuth so, dass dieser Proxy als Zipkin-Endpunkt verwendet wird.
  2. Alternativ können Sie Spring Cloud GCP Trace verwenden, das sich nahtlos in Spring Cloud Sleuth einfügt und die Trace-Daten direkt an Cloud Trace weiterleitet.

In diesem Codelab erfahren Sie, wie Sie eine neue Spring Boot-Anwendung erstellen und Spring Cloud GCP Trace für verteiltes Tracing verwenden.

Lerninhalte

  • So erstellen Sie eine Spring Boot-Java-Anwendung und konfigurieren Cloud Trace.

Voraussetzungen

  • Google Cloud Platform-Projekt
  • Browser, z. B. Chrome oder Firefox
  • Erfahrung mit standardmäßigen Linux-Texteditoren wie Vim, EMACs oder Nano

Wie werden Sie diese Anleitung verwenden?

Nur lesen Lesen und Übungen durchführen

Wie würden Sie Ihre Erfahrung mit der Entwicklung von HTML/CSS-Web-Apps bewerten?

Anfänger Mittelstufe Fortgeschrittene

Wie würden Sie Ihre Erfahrungen mit der Verwendung von Google Cloud Platform-Diensten bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Es handelt sich um einen String, der nicht von Google APIs verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich (kann nach dem Festlegen nicht mehr geändert werden). In der Cloud Console wird automatisch ein eindeutiger String generiert. Normalerweise ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als PROJECT_ID angegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie es mit einem eigenen Namen versuchen und sehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen.
  • Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten
  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/-APIs zu verwenden. Die Durchführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um Kosten zu vermeiden, die über diese Anleitung hinausgehen, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können am kostenlosen Testzeitraum mit einem Guthaben von 300$ teilnehmen.

Google Cloud Shell

Während Sie Google Cloud und Kubernetes von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Wenn Sie die Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

9c92662c6a846a5c.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

9f0e51b578fecce5.png

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Neuen Spring Boot-REST-Dienst erstellen

Nachdem Cloud Shell gestartet wurde, können Sie über die Befehlszeile eine neue Spring Boot-Anwendung mit Spring Initializr generieren:

$ 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

Erstellen Sie einen neuen REST-Controller, indem Sie eine neue Klasse hinzufügen:

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!";
  }
}

Prüfen Sie, ob Sie die richtige JVM-Version für die Anwendung haben:

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

Sie können die Spring Boot-Anwendung wie gewohnt mit dem Spring Boot-Plug-in starten. Wir überspringen die Tests für dieses Lab:

$ ./mvnw -DskipTests spring-boot:run

Anschließend klicken Sie in der Cloud Shell-Symbolleiste auf "Web Preview" (Webvorschau) 3a9b40fafa650b2b.png und wählenPreview on port 8080 (Vorschau auf Port 8080) aus.

3aca52f76c6c22a3.png

Nach kurzer Zeit sollte das Ergebnis angezeigt werden:

6793a3339447cbb5.png

In Cloud Shell sollten Sie auch die Logmeldungen mit Trace-ID und Span-ID sehen:

18d597c388de1ba.png

4. Cloud Trace verwenden

Cloud Trace API aktivieren

Sie müssen die Cloud Trace API aktivieren, bevor Sie Cloud Trace zum Speichern Ihrer Trace-Daten verwenden können. Führen Sie Folgendes aus, um die API zu aktivieren:

$ gcloud services enable cloudtrace.googleapis.com

Standardanmeldedaten für Anwendungen einrichten

Für dieses Lab müssen Sie ein Standardanmeldedaten für Anwendungen konfigurieren. Diese Anmeldedaten werden automatisch vom Spring Cloud GCP Trace Starter übernommen.

Melden Sie sich zuerst an:

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

Klicken Sie auf den Link, um einen neuen Browsertab zu öffnen, und klicken Sie dann auf Zulassen.

85f500de6f5dc0a8.png

Kopieren Sie dann den Bestätigungscode, fügen Sie ihn in Cloud Shell ein und drücken Sie die Eingabetaste. Hier sollten Sie dies sehen:

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

Spring Cloud GCP Trace hinzufügen

In diesem Dienst haben wir Spring Cloud Sleuth bereits für das Tracing verwendet. Fügen wir den Spring Cloud GCP Trace-Starter hinzu, um die Daten an Cloud Trace weiterzuleiten.

Fügen Sie die Spring Cloud GCP Trace-Abhängigkeit hinzu:

pom.xml

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

Standardmäßig erfasst Spring Cloud Sleuth nicht jede Anfrage. Um das Testen zu vereinfachen, erhöhen wir die Stichprobenrate in application.properties auf 100 %, damit wir die Tracedaten sehen können. Außerdem ignorieren wir einige URLs, die uns nicht interessieren:

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

Führen Sie die Anwendung noch einmal aus und verwenden Sie die Cloud Shell-Webvorschau, um die Anwendung aufzurufen:

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

Standardmäßig werden Trace-Daten in Spring Cloud GCP Trace gebatcht und alle 10 Sekunden oder wenn eine Mindestanzahl von Trace-Daten empfangen wurde, gesendet. Dies ist konfigurierbar. Weitere Informationen finden Sie in der Spring Cloud GCP Trace-Referenzdokumentation.

Anfrage an den Dienst senden:

$ curl localhost:8080

Rufen Sie in der Cloud Console Operations → Trace → Trace-Liste auf.

be48cb0f99b5f7c2.png

Beschränken Sie den Zeitraum oben auf eine Stunde. Automatisches Aufladen ist standardmäßig aktiviert. Sobald Trace-Daten eingehen, sollten sie also in der Console angezeigt werden.

3522eef823df39d8.png

Die Tracedaten sollten nach etwa 30 Sekunden angezeigt werden.

9628f6e1d2e75b05.png

Klicken Sie auf den blauen Punkt, um die Trace-Details aufzurufen:

ba9051a8d4f3e725.png

Das war ganz einfach.

5. Zweite Spring Boot-Webanwendung erstellen

Öffnen Sie eine neue Cloud Shell-Sitzung, indem Sie auf das Symbol + klicken:

9799bee5fea95aa6.png

Erstellen Sie in der neuen Sitzung die zweite Spring Boot-Anwendung:

$ 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

Erstellen Sie einen neuen REST-Controller, indem Sie eine neue Klasse hinzufügen:

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";
  }
}

Spring Cloud GCP Trace zu pom.xml hinzufügen

pom.xml

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

Konfigurieren Sie Sleuth so, dass 100% der Anfragen erfasst werden:

src/main/resources/application.properties

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

Schließlich können Sie die Spring Boot-Anwendung auf Port 8081 mit dem Spring Boot-Plugin starten:

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

6. Ersten Dienst aktualisieren, um den zweiten Dienst zu nutzen

Kehren Sie zum ersten Cloud Shell-Sitzungsfenster zurück, während trace-service-two ausgeführt wird, und nehmen Sie Änderungen an trace-service-one vor.

Initialisieren Sie zuerst eine neue RestTemplate-Bean:

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);
        }
}

Rufen Sie in WorkController.meeting() den Besprechungsdienst auf.

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);
  }

  ...
}

Starten Sie den Dienst noch einmal und lösen Sie den Endpunkt über die Befehlszeile aus:

$ 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 beiden Sitzungsfenstern sollten die Logmeldungen angezeigt werden, wobei die Trace-ID von einem Dienst an den anderen weitergegeben wird.

In der Trace-Liste von Cloud Trace sollte der zweite Trace angezeigt werden:

13490977f1638702.png

Sie können auf den neuen blauen Punkt klicken, um die Trace-Details aufzurufen:

ca69ef9cdd13d4aa.png

Sie können auch auf einen beliebigen Span in diesem Diagramm klicken, um die Spandetails aufzurufen.

7. Bericht zur Latenzverteilung und ‑leistung

Wenn Sie Cloud Trace als Speicher für Trace-Daten verwenden, kann Cloud Trace die Daten verwenden, um einen Bericht zur Latenzverteilung zu erstellen. Sie benötigen mehr als 100 Traces, um den Bericht so zu erstellen:

c8713f3d9e51dc25.png

Die ersten 100 Anfragen können Sie mit hey ausführen. Das Tool ist in Cloud Shell vorinstalliert.

$ hey localhost:8080 -n 150

Außerdem kann Cloud Trace unter Analysebericht automatisch Leistungsverschlechterungen desselben Dienstes in zwei verschiedenen Zeiträumen erkennen.

8. Zusammenfassung

In diesem Lab haben Sie zwei einfache Dienste erstellt und mit Spring Cloud Sleuth verteiltes Tracing hinzugefügt. Außerdem haben Sie Spring Cloud GCP verwendet, um die Trace-Informationen an Cloud Trace weiterzuleiten.

9. Glückwunsch!

Sie haben Ihre erste App Engine-Webanwendung geschrieben.

Weitere Informationen

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.