Сьогодні ми озброїмося 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 і B запущені на різних портах.
- Втрата трасування: переконайтеся, що
spring.sleuth.sampler.probabilityвстановлено на1.0для відладки.
Реальне застосування трасування
Ці навички можна застосувати в реальних проєктах. Наприклад, капризна мікросервісна архітектура може почати вередувати, якщо десь переривається виклик. З трасуванням ви швидко знайдете "шкідливого" сервісного сусіда і усунете проблему.
Вітаю, тепер ви готові до успішного пошуку і виправлення багів у розподілених системах!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ