Вопрос 20 · Раздел 17

Что такое exponential backoff

Structured Java interview answer with junior, middle, and senior-level explanation.

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Exponential backoff — стратегия retry, где время ожидания удваивается после каждой неудачной попытки.

Попытка 1: ошибка → ждать 1 сек
Попытка 2: ошибка → ждать 2 сек
Попытка 3: ошибка → ждать 4 сек
Попытка 4: ошибка → ждать 8 сек
Попытка 5: успех! ✅

Зачем: Если сервис перегружен, дать ему больше времени на восстановление.


🟡 Middle Level

Реализация

// ⚠️ ПЛОХОЙ пример для production: Thread.sleep блокирует поток,
// нет jitter, нет max cap. Используйте Resilience4j или Spring Retry.
long baseDelay = 1000; // 1 секунда
double multiplier = 2.0;

for (int attempt = 0; attempt < maxAttempts; attempt++) {
    try {
        return callService();
    } catch (Exception e) {
        long delay = (long) (baseDelay * Math.pow(multiplier, attempt));
        Thread.sleep(delay);
    }
}

С jitter

// Jitter добавляет случайность для предотвращения thundering herd
// Это "equal jitter" вариант. AWS рекомендует "full jitter":
// sleep = random(0, min(cap, base * 2^attempt))
long delay = (long) (baseDelay * Math.pow(multiplier, attempt));
long jitter = random.nextInt((int)(delay * 0.1));
delay += jitter;

Типичные ошибки

  1. Без jitter:
    Все клиенты retry одновременно → thundering herd → сервис снова падает
    

Когда НЕ использовать exponential backoff

  • Идемпотентные read-операции — простой retry ok
  • Критичные по времени операции (real-time) — backoff добавляет непредсказуемость
  • Клиентские запросы от пользователя — пользователь не будет ждать 30 секунд backoff

🔴 Senior Level

Full jitter formula

// AWS рекомендует: full jitter
long delay = min(cap, base * pow(multiplier, attempt)) + random(0, base)

Production Experience

Resilience4j:

RetryConfig config = RetryConfig.custom()
    .maxAttempts(5)
    .intervalFunction(IntervalFunction.ofExponentialBackoff(1000, 2.0))
    .build();

Best Practices

✅ Exponential backoff + jitter
✅ Cap на максимальную задержку
✅ Лимит попыток
✅ Только для retryable ошибок

❌ Без cap (можно ждать минуты)
❌ Без jitter
❌ Для всех типов ошибок

🎯 Шпаргалка для интервью

Обязательно знать:

  • Exponential backoff — delay удваивается: 1s → 2s → 4s → 8s
  • Jitter добавляет случайность: AWS рекомендует full jitter = random(0, min(cap, base * 2^attempt))
  • Cap (максимальная задержка) обязателен — без cap можно ждать минуты
  • Только для retryable ошибок — не для 4xx, не для business exceptions
  • НЕ использовать для идемпотентных read (простой retry ok), real-time операций, клиентских запросов
  • Resilience4j: IntervalFunction.ofExponentialBackoff(base, multiplier)
  • Thread.sleep в production — плохо, используйте Resilience4j или Spring Retry

Частые уточняющие вопросы:

  • Full jitter vs equal jitter? Full jitter = random(0, base2^attempt), equal jitter = delay + random(0, delay0.1). Full jitter лучше предотвращает thundering herd.
  • Какой cap выбрать? Зависит от SLA — обычно 30-60 секунд максимум.
  • Почему Thread.sleep плох? Блокирует поток, нет jitter, нет max cap — используйте Resilience4j.
  • Когда НЕ использовать backoff? Read-операции (простой retry ok), real-time, клиентские запросы от пользователя.

Красные флаги (НЕ говорить):

  • “Backoff без cap — надёжнее” — нет, можно ждать бесконечно
  • “Jitter не нужен для малого трафика” — всё равно нужен, клиенты могут синхронизироваться
  • “Backoff для 404 ошибок” — нет, сервер не починится сам
  • “Thread.sleep — production-ready” — нет, блокирует поток, нет jitter

Связанные темы:

  • [[19. Что такое паттерн Retry и как его правильно использовать]]
  • [[17. Как обеспечить отказоустойчивость микросервисов]]
  • [[15. Как организовать коммуникацию между микросервисами]]
  • [[5. Что такое паттерн Circuit Breaker]]
  • [[21. Как мониторить распределённую систему микросервисов]]