Sobes.tech
Назад к вопросам
Senior
8

Расскажи про Circuit Breaker, который ты реализовывал для интеграции с внешней системой.

Компании, где спрашивали
Velenes.Tech

Ответ от нейросети

sobes.tech AI

Circuit Breaker — это паттерн, который помогает защитить систему от повторяющихся неудачных вызовов к внешним сервисам, предотвращая тем самым каскадные отказы и повышая устойчивость приложения.

В одном из проектов на Java я реализовывал Circuit Breaker для интеграции с внешним API, который иногда становился недоступен или отвечал с ошибками.

Основные моменты реализации:

  • Состояния:

    • Closed — все запросы проходят, пока не превысится порог ошибок.
    • Open — запросы блокируются, возвращается ошибка сразу.
    • Half-Open — после таймаута пробуем отправить несколько запросов, чтобы проверить восстановление.
  • Логика:

    • Считается количество неудачных вызовов за определённый период.
    • Если количество ошибок превышает порог, переключаемся в состояние Open.
    • Через заданный таймаут переходим в Half-Open и пробуем запрос.
    • Если запрос успешен — возвращаемся в Closed, иначе снова Open.

Пример упрощённой реализации на Java с использованием AtomicInteger и enum для состояний:

public class CircuitBreaker {
    private enum State { CLOSED, OPEN, HALF_OPEN }

    private State state = State.CLOSED;
    private int failureCount = 0;
    private final int failureThreshold = 5;
    private long lastFailureTime = 0;
    private final long retryTimePeriod = 10000; // 10 секунд

    public synchronized boolean allowRequest() {
        if (state == State.OPEN) {
            if (System.currentTimeMillis() - lastFailureTime > retryTimePeriod) {
                state = State.HALF_OPEN;
                return true;
            }
            return false;
        }
        return true;
    }

    public synchronized void recordSuccess() {
        failureCount = 0;
        state = State.CLOSED;
    }

    public synchronized void recordFailure() {
        failureCount++;
        lastFailureTime = System.currentTimeMillis();
        if (failureCount >= failureThreshold) {
            state = State.OPEN;
        }
    }
}

Такой Circuit Breaker интегрировался в слой вызова внешнего API: перед запросом проверялось allowRequest(), после ответа — вызывались recordSuccess() или recordFailure().

Это позволило значительно снизить нагрузку на систему при проблемах с внешним сервисом и улучшить пользовательский опыт за счёт быстрого отказа и последующего восстановления.