Какие паттерны и практики используются для обработки ошибок в микросервисной архитектуре?

«Какие паттерны и практики используются для обработки ошибок в микросервисной архитектуре?» — вопрос из категории Архитектура, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Надежное взаимодействие микросервисов требует стратегий для отказоустойчивости.

1. Паттерн Circuit Breaker (Предохранитель):

  • Цель: Предотвратить каскадные сбои и дать временно неработающему сервису восстановиться.
  • Реализация: Библиотеки Resilience4j или Spring Cloud Circuit Breaker.
  • Состояния: CLOSED (все работает), OPEN (сбои, вызовы блокируются), HALF_OPEN (пробные вызовы для проверки восстановления).
@CircuitBreaker(name = "inventoryService", fallbackMethod = "getDefaultInventory")
public InventoryResponse checkInventory(Long productId) {
    // Вызов внешнего сервиса
    return restTemplate.getForObject(...);
}

public InventoryResponse getDefaultInventory(Long productId, Exception e) {
    // Fallback-логика: вернуть значение по умолчанию или из кэша
    return new InventoryResponse(productId, 0);
}

2. Паттерн Retry (Повтор):

  • Цель: Справиться с временными сбоями (таймауты сети, кратковременная недоступность).
  • Важно: Использовать экспоненциальную задержку (exponential backoff) и jitter (случайную добавку), чтобы не перегружать восстанавливающийся сервис.

3. Паттерн Fallback (Резервный вариант):

  • Цель: Предоставить альтернативный ответ или действие при сбое (например, кэшированные данные, значение по умолчанию, вызов другого сервиса).

4. Dead Letter Queue (DLQ - очередь "мертвых" писем):

  • Цель: В асинхронной коммуникации (через брокеры сообщений) изолировать сообщения, которые не удалось обработать после нескольких попыток, для последующего анализа.

5. Паттерн Saga:

  • Цель: Управлять распределенными транзакциями. При сбое на одном шаге выполняются компенсирующие транзакции для отката изменений в других сервисах.

Дополнительные практики:

  • Таймауты: Всегда устанавливайте разумные таймауты на вызовы.
  • Лимитирование запросов (Rate Limiting): Защита сервиса от перегрузки.
  • Полноценное логирование и мониторинг (распределенная трассировка, метрики состояния Circuit Breaker).