Распределенная трассировка с помощью Spring Cloud Sleuth и Cloud Trace.

1. Обзор

Распределенная трассировка важна для получения информации и обеспечения наблюдаемости в многоуровневой микросервисной архитектуре. При наличии цепочек вызовов сервисов, от сервиса A к сервису B и к сервису C, важно понимать, были ли вызовы успешными, а также задержку на каждом шаге.

В Spring Boot вы можете использовать Spring Cloud Sleuth для беспрепятственного добавления инструментов распределенной трассировки в ваше приложение. По умолчанию он может пересылать данные трассировки в Zipkin.

В Google Cloud Platform есть Cloud Trace — управляемый сервис, позволяющий хранить данные трассировки без необходимости управлять собственным экземпляром Zipkin или хранилищем. Cloud Trace также может создавать отчеты о распределении задержек и автоматически обнаруживать регрессии производительности.

У вас есть два варианта использования Cloud Trace в приложении Spring Boot:

  1. Используйте прокси-сервер Stackdriver Trace Zipkin и просто настройте Spring Cloud Sleuth для использования этого прокси в качестве конечной точки Zipkin.
  2. Или же используйте Spring Cloud GCP Trace, который легко интегрируется со Spring Cloud Sleuth и пересылает данные трассировки непосредственно в Cloud Trace.

В этом практическом занятии вы узнаете, как создать новое приложение Spring Boot и использовать Spring Cloud GCP Trace для распределенной трассировки.

Что вы узнаете

  • Как создать Java-приложение на Spring Boot и настроить Cloud Trace.

Что вам понадобится

  • Проект Google Cloud Platform
  • Браузер, например Chrome или Firefox.
  • Знание стандартных текстовых редакторов Linux, таких как Vim, EMACs или Nano.

Как вы будете использовать этот учебник?

Прочитайте только от начала до конца. Прочитайте текст и выполните упражнения.

Как бы вы оценили свой опыт разработки веб-приложений на HTML/CSS?

Новичок Средний Профессионал

Как бы вы оценили свой опыт использования сервисов Google Cloud Platform?

Новичок Средний Профессионал

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы всегда можете его изменить.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта (обычно обозначается как PROJECT_ID ). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он сохраняется на протяжении всего проекта.
  • К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
  1. Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

Google Cloud Shell

Хотя Google Cloud и Kubernetes можно запускать удаленно с ноутбука, в этом практическом занятии мы будем использовать Google Cloud Shell — среду командной строки, работающую в облаке.

Активировать Cloud Shell

  1. В консоли Cloud нажмите «Активировать Cloud Shell» . 853e55310c205094.png .

55efc1aaa7a4d3ad.png

Если вы запускаете Cloud Shell впервые, вам будет показан промежуточный экран с описанием его возможностей. Если вам был показан промежуточный экран, нажмите «Продолжить» .

9c92662c6a846a5c.png

Подготовка и подключение к Cloud Shell займут всего несколько минут.

9f0e51b578fecce5.png

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Большая часть, если не вся, ваша работа в этом практическом задании может быть выполнена с помощью браузера.

После подключения к Cloud Shell вы увидите, что прошли аутентификацию и что проект настроен на ваш идентификатор проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить свою аутентификацию:
gcloud auth list

вывод команды

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить это с помощью следующей команды:

gcloud config set project <PROJECT_ID>

вывод команды

Updated property [core/project].

3. Создайте новый REST-сервис Spring Boot.

После запуска Cloud Shell вы можете использовать командную строку для создания нового приложения Spring Boot с помощью 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

Создайте новый REST-контроллер, добавив новый класс:

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

Убедитесь, что у вас установлена ​​правильная версия JVM для приложения:

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

Приложение Spring Boot можно запустить обычным способом с помощью плагина Spring Boot. Давайте пропустим тесты в этой лабораторной работе:

$ ./mvnw -DskipTests spring-boot:run

После запуска приложения нажмите на значок «Предварительный просмотр веб-страницы». 3a9b40fafa650b2b.png В панели инструментов Cloud Shell выберите «Предварительный просмотр на порту 8080» .

3aca52f76c6c22a3.png

После непродолжительного ожидания вы должны увидеть результат:

6793a3339447cbb5.png

В Cloud Shell вы также должны увидеть сообщения журнала с идентификаторами трассировки и сегментов:

18d597c388de1ba.png

4. Использование Cloud Trace

Включить API Cloud Trace

Перед использованием Cloud Trace для хранения данных трассировки необходимо сначала включить API Cloud Trace. Для включения API выполните следующую команду:

$ gcloud services enable cloudtrace.googleapis.com

Настройка учетных данных приложения по умолчанию

Для выполнения этой лабораторной работы вам потребуется настроить учетные данные приложения по умолчанию. Эти учетные данные будут автоматически подхвачены стартером Spring Cloud GCP Trace.

Сначала войдите в систему:

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

Нажмите на ссылку, чтобы открыть новую вкладку браузера, а затем нажмите «Разрешить».

85f500de6f5dc0a8.png

Затем скопируйте и вставьте код подтверждения обратно в Cloud Shell и нажмите Enter. Вы должны увидеть:

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

В этом сервисе мы уже использовали Spring Cloud Sleuth для трассировки. Давайте добавим стартовый пакет Spring Cloud GCP Trace для пересылки данных в Cloud Trace.

Добавьте зависимость 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>

По умолчанию Spring Cloud Sleuth не отслеживает каждый запрос. Чтобы упростить тестирование, увеличьте частоту выборки до 100% в application.properties , чтобы убедиться, что мы видим данные трассировки, а также игнорируйте некоторые URL-адреса, которые нас не интересуют:

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

Запустите приложение еще раз и воспользуйтесь функцией предварительного просмотра в веб-интерфейсе Cloud Shell, чтобы просмотреть его содержимое:

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

По умолчанию Spring Cloud GCP Trace объединяет данные трассировки в пакеты и отправляет их каждые 10 секунд или при получении минимального количества данных трассировки. Это можно настроить, и для получения дополнительной информации вы можете обратиться к справочной документации Spring Cloud GCP Trace .

Отправьте запрос в службу поддержки:

$ curl localhost:8080

В консоли Cloud перейдите в раздел OperationsTraceTrace list

be48cb0f99b5f7c2.png

Вверху сузьте временной диапазон до 1 часа. По умолчанию включена функция автоматической перезагрузки . Таким образом, по мере поступления данных трассировки они должны отображаться в консоли!

3522eef823df39d8.png

Данные трассировки должны появиться примерно через 30 секунд.

9628f6e1d2e75b05.png

Нажмите на синюю точку, чтобы увидеть подробности трассировки:

ba9051a8d4f3e725.png

Это было довольно просто!

5. Создайте второе веб-приложение Spring Boot.

Откройте новую сессию Cloud Shell, нажав на значок «+» :

9799bee5fea95aa6.png

В новой сессии создайте второе приложение 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

Создайте новый REST-контроллер, добавив новый класс:

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 в файл 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>

Настройте Sleuth так, чтобы он отбирал данные из 100% запросов:

src/main/resources/application.properties

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

Наконец, вы можете запустить приложение Spring Boot на порту 8081 с помощью плагина 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. Обновите первую службу, чтобы она использовала вторую службу.

Пока запущена trace-service-two , вернитесь в первое окно сессии Cloud Shell и внесите изменения в команду trace-service-one .

Сначала инициализируйте новый компонент 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);
        }
}

В WorkController.meeting() выполните вызов к службе Meeting.

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

  ...
}

Перезапустите службу и вызовите конечную точку из командной строки:

$ 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

В обоих окнах сеанса вы должны увидеть сообщения журнала, в которых идентификатор трассировки передается от одной службы к другой.

В списке трассировок Cloud Trace вы должны увидеть вторую трассировку:

13490977f1638702.png

Вы можете нажать на новую синюю точку и увидеть подробные данные трассировки:

ca69ef9cdd13d4aa.png

Вы также можете щелкнуть по любому участку на этой схеме, чтобы просмотреть подробную информацию о нем.

7. Отчет о распределении задержки и производительности

При использовании Cloud Trace в качестве хранилища данных трассировки, Cloud Trace может использовать эти данные для построения отчета о распределении задержек. Для создания подобного отчета потребуется более 100 трассировок :

c8713f3d9e51dc25.png

Вы можете выполнить первые 100+ запросов, используя hey , который предустановлен в Cloud Shell !

$ hey localhost:8080 -n 150

Кроме того, Cloud Trace может автоматически обнаруживать снижение производительности одной и той же службы в двух разных временных периодах в отчете об анализе .

8. Резюме

В этой лабораторной работе вы создали 2 простых сервиса, добавили распределенную трассировку с помощью Spring Cloud Sleuth и использовали Spring Cloud GCP для пересылки информации трассировки в Cloud Trace.

9. Поздравляем!

Вы научились писать своё первое веб-приложение на App Engine!

Узнать больше

Лицензия

Данная работа распространяется под лицензией Creative Commons Attribution 2.0 Generic.