Очень часто используют такую конструкцию:
curl https://api.bashtex.com || sleep 5 && curl https://api.bashtex.com
Или ещё хуже: в цикле с фиксированной паузой.
Это неуправляемый retry, который: создает лишнюю нагрузку, не учитывает тип ошибки, не масштабируется и может устроить небольшой DDoS при массовом падении сервиса.
Правильный подход - retry с exponential backoff.
▪️ Почему sleep 5 - это плохая стратегия.
Представим: API лежит 2 минуты. 100 серверов начинают делать: запрос -> sleep 5 -> запрос -> sleep 5 → …
Ты получаешь синхронную атаку на уже мертвый сервис.
Exponential backoff делает паузы все длиннее: 1s -> 2s -> 4s -> 8s -> 16s -> ...
Это: снижает нагрузку, дает сервису восстановиться, уменьшает каскадные падения
🛠 Базовая retry-обертка
retry() {
local max_attempts=$1
shift
local attempt=1
local delay=1
while true; do
"$@" && return 0
if (( attempt >= max_attempts )); then
echo "Команда не удалась после $attempt попыток"
return 1
fi
echo "Попытка $attempt неудачна. Повтор через $delay сек."
sleep "$delay"
attempt=$(( attempt + 1 ))
delay=$(( delay * 2 ))
done
}
▪️ Использование:
retry 5 curl -fsS https://api.bashtex.com
▪️ Что здесь происходит
"$@" - передаем любую команду;выходной код управляет retry;
задержка удваивается;
максимум попыток ограничен.
▪️ Когда retry вреден
при логических ошибках (401, 403);
если операция не идемпотентна;
если сервис возвращает fatal error.
Retry должен применяться к временным ошибкам, а не ко всем подряд.
BashTex 📱 #bash #utils