На главную
DevOps и серверы
Повторы с экспоненциальной задержкой
Экспоненциальная задержка между повторными попытками: расписание пауз с потолком и разбросом (jitter), сколько всего ждать до последней попытки и готовый код на JavaScript и Python.
Расписание
| Повтор | Пауза без разброса | Пауза, от — до | Прошло к этому моменту |
|---|---|---|---|
| 1 | 1 с | 0 с — 1 с | 0 с — 1 с |
| 2 | 2 с | 0 с — 2 с | 0 с — 3 с |
| 3 | 4 с | 0 с — 4 с | 0 с — 7 с |
| 4 | 8 с | 0 с — 8 с | 0 с — 15 с |
| 5 | 16 с | 0 с — 16 с | 0 с — 31 с |
| 6 | 30 с | 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));
}
}
}