Как микросервисы общаются между собой?

«Как микросервисы общаются между собой?» — вопрос из категории Архитектура, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В микросервисной архитектуре, над которой я работал, сервисы взаимодействуют в основном двумя способами: синхронно по HTTP и асинхронно через брокер сообщений.

1. Синхронное взаимодействие (REST/gRPC): Используется, когда сервису нужен немедленный ответ. Например, сервис заказов (Order Service) запрашивает у сервиса каталога (Catalog Service) актуальную цену товара.

// Пример на Java с Spring Boot и Feign Client
@FeignClient(name = "catalog-service")
public interface CatalogServiceClient {
    @GetMapping("/api/products/{id}")
    Product getProduct(@PathVariable("id") Long productId);
}
// Использование в Order Service
Product product = catalogServiceClient.getProduct(orderItem.getProductId());

Недостатки: Создает жесткую связь и может привести к каскадным сбоям.

2. Асинхронное взаимодействие (через брокер, например, Kafka или RabbitMQ): Используется для декoupling и обработки событий. Например, при создании заказа Order Service публикует событие OrderCreated, а Notification Service и Inventory Service подписываются на него.

// Order Service (Publisher)
kafkaTemplate.send("order-events", new OrderCreatedEvent(orderId, userId));

// Notification Service (Consumer)
@KafkaListener(topics = "order-events", groupId = "notification-group")
public void handleOrderEvent(OrderCreatedEvent event) {
    // Отправляем email пользователю
    emailService.sendOrderConfirmation(event.getUserId(), event.getOrderId());
}

С точки зрения тестирования (QA):

  • Для синхронных API мы пишем интеграционные тесты, мокая внешние зависимости с помощью WireMock.
  • Для асинхронных сценариев мы используем тесты, которые публикуют сообщение в тестовый топик Kafka и затем проверяют, что потребитель корректно обработал его и выполнил нужные действия (например, обновил базу данных).
  • Критически важна трассировка запросов (Distributed Tracing), например, через Jaeger, чтобы отслеживать путь запроса по всем сервисам.