Сегодня мы вооружимся Sleuth и Zipkin, чтобы реализовать трассировку запросов между несколькими микросервисами. У нас будет два простых микросервиса:
- Сервис A — отправляет HTTP-запрос к Сервису B.
- Сервис B — обрабатывает запрос и отвечает.
На выходе мы сможем визуализировать трассировку каждого запроса в Zipkin UI. Давайте начнем!
Подключение зависимостей
Для работы нам понадобятся:
Spring BootSpring Cloud SleuthSpring Web- Подключение к Zipkin (либо локально, либо через Docker).
Настройка pom.xml для Сервиса A и B
Добавим нужные зависимости в pom.xml наших проектов. Начнем с того, чтобы подключить Sleuth и Spring Web:
<dependencies>
<!-- Spring Web (для обработки HTTP-запросов) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Sleuth (для трассировки запросов) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Zipkin (для отправки данных трассировки в Zipkin) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
</dependencies>
Обновите maven с помощью команды mvn install, если ваш любимый IDE этого ещё не сделала.
Настройка Zipkin
Если у вас ещё нет Zipkin, легче всего развернуть его с помощью Docker:
docker run -d -p 9411:9411 openzipkin/zipkin
После запуска Zipkin будет доступен по адресу: http://localhost:9411. Откройте его в браузере — нас позже ждет красивая визуализация трассировки.
Создание микросервисов
Сервис A будет отвечать за отправку запросов к Сервису B. Мы добавим один REST-эндпоинт, который делает HTTP-запрос к другому сервису.
В папке src/main/java создадим класс контроллера:
@RestController
@RequestMapping("/serviceA")
public class ServiceAController {
private final RestTemplate restTemplate;
public ServiceAController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/callB")
public String callServiceB() {
// Отправка GET-запроса к Сервису B
String response = restTemplate.getForObject("http://localhost:8081/serviceB/hello", String.class);
return "Ответ от Сервиса B: " + response;
}
}
Обратите внимание, мы используем RestTemplate для отправки запроса. Этот запрос будет "отслеживаться" Sleuth автоматически.
Теперь добавим бин RestTemplate, чтобы Spring Boot мог его использовать:
@Configuration
public class ServiceAConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Сервис B будет обрабатывать HTTP-запрос от Сервиса A и возвращать ответ.
В папке src/main/java создайте контроллер для Сервиса B:
@RestController
@RequestMapping("/serviceB")
public class ServiceBController {
@GetMapping("/hello")
public String sayHello() {
return "Привет от Сервиса B!";
}
}
Конфигурация трассировки
Sleuth автоматически добавляет нужные "метки" (traceId, spanId) к логам и запросам. Однако нам нужно настроить его для отправки данных в Zipkin.
Добавьте следующие настройки в файлы application.yml для обоих сервисов:
spring:
application:
name: service-a # или service-b, меняем для каждого сервиса
sleuth:
sampler:
probability: 1.0 # 100% запросов будут трассироваться
zipkin:
base-url: http://localhost:9411 # URL Zipkin
enabled: true
Обратите внимание, что настройка sampler.probability определяет, какой процент запросов будет трассироваться. Мы установили 1.0 для отладки (это 100%).
Запуск и тестирование
Шаг 1: Запустите оба сервиса
- Запустите Сервис B (он должен слушать порт
8081). - Запустите Сервис A (он должен слушать порт
8080).
Шаг 2: Тестируйте трассировку
- Отправьте запрос к Сервису A с помощью браузера или любого HTTP-клиента (например, Postman):
GET http://localhost:8080/serviceA/callB - В ответ вы должны получить:
Ответ от Сервиса B: Привет от Сервиса B!
Проверка трассировки в Zipkin UI
Перейдите в http://localhost:9411, чтобы увидеть трассировку. Посмотрите, как запрос путешествует из Сервиса A в Сервис B, а затем обратно. В UI будут указаны:
- Trace ID — уникальный идентификатор запроса.
- Span ID — отдельные части трассировки (например, HTTP-запросы).
Обратная связь и тонкие моменты
- Типичные ошибки: если трассировка не отображается в Zipkin, проверьте настройку
base-urlи убедитесь, что Zipkin запущен. - Проблемы с портами: убедитесь, что Сервис A и Б запущены на разных портах.
- Потеря трассировки: убедитесь, что
spring.sleuth.sampler.probabilityустановлено на1.0для отладки.
Реальное применение трассировки
Эти навыки могут быть применены в реальных проектах. Например, сложная барышня микросервисная архитектура может начать капризничать, если где-то прерывается вызов. С трассировкой вы сможете быстро найти "вредного" сервисного соседа и устранить проблему.
Поздравляю, теперь вы готовы к успешному поиску и устранению багов в распределённых системах!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ