0Pricing
Go Academy · Урок

Обработка ошибок и логика повторных попыток

Проверяйте коды состояния и реализуйте повторные попытки

«Обработка ошибок и логика повторных попыток» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Ошибки HTTP не являются ошибками Go

Статус HTTP 404 или 500 не является ошибкой Go — http.Client.Do возвращает ошибку nil для любого корректного HTTP-ответа. Явно проверяйте resp.StatusCode.

Оборачивание ошибок

Добавляйте к ошибкам контекст с помощью fmt.Errorf("operation: %w", err), чтобы вызывающий код мог проверить причину с помощью errors.Is / errors.As.

if err != nil {
    return fmt.Errorf("fetch users: %w", err)
}

Ошибки, допускающие и не допускающие повторных попыток

Повторяйте попытку при сетевых тайм-аутах, статусе 429 «Слишком много запросов» и статусе 503 «Сервис недоступен». Не повторяйте попытку при статусах 400 «Некорректный запрос», 401 «Не авторизован» и 404 «Не найдено» — повторная попытка не поможет.

Экспоненциальное увеличение паузы

Увеличивайте интервал между каждой повторной попыткой, чтобы снизить нагрузку на перегруженный сервер. Простая реализация:

for i := 0; i < maxRetries; i++ {
    resp, err := client.Do(req)
    if err == nil && resp.StatusCode < 500 { break }
    time.Sleep(time.Duration(math.Pow(2, float64(i))) * time.Second)
}

Случайная добавка

Добавляйте случайную величину к паузе между попытками, чтобы несколько клиентов не повторяли запросы одновременно (эффект стада).

wait := time.Duration(math.Pow(2, float64(i)))*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond

Заголовок Retry-After

Ответ 429 часто содержит заголовок Retry-After. Разберите его и учитывайте вместо использования фиксированной паузы.

retryAfter := resp.Header.Get("Retry-After")
if secs, err := strconv.Atoi(retryAfter); err == nil {
    time.Sleep(time.Duration(secs) * time.Second)
}

Повторные попытки с учётом контекста

Проверяйте контекст перед каждой повторной попыткой, чтобы прекратить их, если запрос был отменён.

for i := 0; i < maxRetries; i++ {
    if ctx.Err() != nil { return nil, ctx.Err() }
    // attempt
}

Пользовательские типы ошибок

Определяйте типизированные ошибки HTTP, содержащие код состояния и тело ответа, чтобы вызывающий код мог принимать точные решения о повторных попытках.

type HTTPError struct {
    Status int
    Body   string
}
func (e *HTTPError) Error() string { return fmt.Sprintf("HTTP %d: %s", e.Status, e.Body) }

Варианты библиотек

Для логики повторных попыток в рабочей среде рассмотрите hashicorp/go-retryablehttp или cenkalti/backoff с настраиваемыми политиками пауз, максимальным числом повторных попыток и поддержкой контекста.

Ключи идемпотентности

Для повторяемых запросов POST включайте в заголовок ключ идемпотентности (UUID), чтобы сервер устранял дубликаты и возвращал тот же результат, не создавая дублирующиеся ресурсы.

Размыкатель цепи

Размыкатель цепи отслеживает частоту сбоев и прекращает отправлять запросы в неработающий сервис на период охлаждения. Библиотеки вроде sony/gobreaker реализуют этот шаблон.

Быстрая проверка

Зачем добавлять случайную величину к экспоненциально увеличивающейся паузе?

Итоги: обработка ошибок и повторные попытки

Основные положения:

  • Проверяйте resp.StatusCode — ошибки HTTP не являются ошибками Go
  • Повторяйте попытки при 429, 503 и сетевых тайм-аутах, но не при клиентских ошибках 4xx
  • Экспоненциальное увеличение паузы со случайной добавкой предотвращает эффект стада
  • Всегда проверяйте контекст перед повторной попыткой

Часто задаваемые вопросы

Урок «Обработка ошибок и логика повторных попыток» бесплатный?

Да — полный текст урока «Обработка ошибок и логика повторных попыток» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Обработка ошибок и логика повторных попыток»?

Проверяйте коды состояния и реализуйте повторные попытки Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Обработка ошибок и логика повторных попыток»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Выполнение HTTP-запросов
  2. Настройка тайм-аутов и заголовков
  3. Декодирование ответов JSON
  4. Обработка ошибок и логика повторных попыток
← Назад к Go Academy