Gymterview
middle

Что такое паттерн Circuit Breaker?

Circuit Breaker (автоматический выключатель) — это паттерн отказоустойчивости, который предотвращает каскадные сбои в распределённой системе, «размыкая цепь» при обнаружении проблем с вызываемым сервисом.

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

Три состояния

Пример
   ┌─────────┐   Порог ошибок превышен   ┌──────────┐
   │ CLOSED  │ ──────────────────────────► │   OPEN   │
   │(нормаль)│                             │(отказ)   │
   └────▲────┘                             └────┬─────┘
        │                                       │
        │ Пробный вызов успешен    Таймаут      │
        │                         истёк         │
   ┌────┴────────┐◄─────────────────────────────┘
   │ HALF-OPEN   │
   │(проверка)   │ ── Пробный вызов неуспешен ──► OPEN
   └─────────────┘
  • CLOSED — запросы проходят нормально. Счётчик ошибок ведётся.
  • OPEN — все запросы мгновенно возвращают fallback-ответ, не дожидаясь таймаута.
  • HALF-OPEN — пропускается ограниченное число пробных запросов. Если они успешны — CLOSED, иначе — OPEN.
Реализация с Resilience4j
// Зависимость: resilience4j-spring-boot3

@Service
public class PaymentService {

    private final CustomerClient customerClient;

    @CircuitBreaker(name = "customerService", fallbackMethod = "getCustomerFallback")
    public CustomerDto getCustomer(Long customerId) {
        return customerClient.getCustomer(customerId);
    }

    // Fallback-метод — вызывается при открытом circuit breaker
    private CustomerDto getCustomerFallback(Long customerId, Throwable t) {
        log.warn("Circuit breaker активирован для customer-service: {}", t.getMessage());
        return CustomerDto.builder()
            .id(customerId)
            .name("Неизвестный клиент (сервис недоступен)")
            .build();
    }
}
# application.yml — конфигурация Resilience4j
resilience4j:
  circuitbreaker:
    instances:
      customerService:
        sliding-window-type: COUNT_BASED
        sliding-window-size: 10
        failure-rate-threshold: 50       # Открыть при 50% ошибок
        wait-duration-in-open-state: 30s # Ждать 30 сек перед HALF-OPEN
        permitted-number-of-calls-in-half-open-state: 3
        record-exceptions:
          - java.io.IOException
          - java.net.SocketTimeoutException
          - org.springframework.web.client.HttpServerErrorException

На собеседовании: обязательно назовите три состояния (CLOSED, OPEN, HALF-OPEN) и объясните переходы между ними. Упомяните Resilience4j как замену устаревшего Hystrix. Частая ошибка — забыть про fallback-стратегию.