На главную

DevOps и серверы

Повторы с экспоненциальной задержкой

Экспоненциальная задержка между повторными попытками: расписание пауз с потолком и разбросом (jitter), сколько всего ждать до последней попытки и готовый код на JavaScript и Python.

Расписание

ПовторПауза без разбросаПауза, от — доПрошло к этому моменту
11 с0 с — 1 с0 с — 1 с
22 с0 с — 2 с0 с — 3 с
34 с0 с — 4 с0 с — 7 с
48 с0 с — 8 с0 с — 15 с
516 с0 с — 16 с0 с — 31 с
630 с0 с — 30 с0 с — 1 мин 1 с

Разброс нужен, чтобы тысяча клиентов, упавших одновременно, не вернулись тоже одновременно. Full jitter даёт самую равномерную нагрузку, equal — гарантирует хотя бы половину паузы (по статье AWS Architecture Blog «Exponential Backoff And Jitter»).

Код

async function retry(call, { base = 1, factor = 2, cap = 30, retries = 6 } = {}) {
  let prev = base;
  for (let attempt = 0; ; attempt += 1) {
    try {
      return await call();
    } catch (err) {
      if (attempt === retries) throw err;
      const delay = Math.min(cap, base * factor ** attempt);
      const sleep = Math.random() * delay;
      prev = sleep;
      await new Promise((resolve) => setTimeout(resolve, sleep * 1000));
    }
  }
}