Короткий ответ
Экспоненциальная задержка увеличивает паузу между попытками, снижая нагрузку на восстанавливающуюся зависимость; джиттер добавляет случайный разброс, чтобы множество клиентов, начавших ретраить одновременно, не синхронизировались и не создавали повторные волновые всплески нагрузки.
Как это работает подробнее
Базовая задержка умножается на 2 в степени номера попытки и ограничивается максимумом (cap); джиттер — случайное значение, добавляемое или умножаемое к этой задержке (full jitter, equal jitter).
Пример кода
example.py
import random
def backoff_delay(attempt, base=1.0, cap=30.0):
exp = min(cap, base * (2 ** attempt))
return random.uniform(0, exp) # full jitter
for attempt in range(5):
try:
return call_external()
except TransientError:
time.sleep(backoff_delay(attempt))Что использовать на практике
- Практика. Без джиттера сотни клиентов, получивших ошибку в один момент, будут ретраить синхронно по одному графику, создавая повторяющиеся пики нагрузки (thundering herd); с джиттером повторные попытки размазываются по времени.
Подводные камни
- Риск. Ставить фиксированное количество ретраев без ограничения общего времени ожидания; забывать ограничить максимальную задержку (cap), получая неоправданно долгие паузы на поздних попытках.