Расскажи про Circuit Breaker, который ты реализовывал для интеграции с внешней системой.
Ответ от нейросети
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().
Это позволило значительно снизить нагрузку на систему при проблемах с внешним сервисом и улучшить пользовательский опыт за счёт быстрого отказа и последующего восстановления.