Отложенный повтор
Повторяйте попытки с увеличением интервала
«Отложенный повтор» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Зачем нужны повторы
Временные сбои, истечения времени ожидания, разрывы соединения и кратковременные ответы 503 часто исчезают при второй попытке. Повторная попытка превращает операцию flaky в надёжную, не беспокоя вызывающую сторону.
Наивные повторы опасны
Немедленные повторы в плотном цикле перегружают испытывающий трудности сервис и могут вызвать лавину повторных запросов. Между попытками нужны задержки, причём эти задержки должны увеличиваться.
Экспоненциальная задержка
Экспоненциальная задержка после каждого сбоя удваивает время ожидания: 100 мс, 200 мс, 400 мс, 800 мс. Это даёт нижестоящему сервису время на восстановление.
delay := 100 * time.Millisecond
for attempt := 0; attempt < 5; attempt++ {
// try, on failure:
time.Sleep(delay)
delay *= 2
}Добавление случайного разброса
Если многие клиенты синхронно увеличивают задержку, они повторяют запросы в один и тот же момент, создавая эффект толпы. Случайный разброс немного изменяет каждую задержку, распределяя повторы во времени.
jitter := time.Duration(rand.Int63n(int64(delay) / 2))
time.Sleep(delay + jitter)Ограничение задержки
Экспоненциальный рост быстро приводит к огромным значениям. Ограничьте задержку сверху, чтобы не ждать между попытками несколько минут.
if delay > 2*time.Second {
delay = 2 * time.Second
}Ограничение числа попыток
Всегда ограничивайте число попыток. После достижения ограничения верните последнюю ошибку, чтобы вызывающая сторона могла решить, что делать дальше, вместо бесконечных повторов.
Повторяйте только идемпотентные операции
Повтор безопасен только тогда, когда операцию можно выполнить дважды без вреда. GET является идемпотентным, а неидемпотентный POST, списывающий средства с карты, не следует повторять бездумно. При необходимости используйте ключи идемпотентности.
Полный пример повторов с задержкой
Эта программа повторяет вызов функции, которая дважды завершается ошибкой, а затем успешно выполняется, каждый раз удваивая задержку. Она использует только стандартную библиотеку.
package main
import (
"errors"
"fmt"
"time"
)
func flaky(attempt int) error {
if attempt < 2 {
return errors.New("temporary failure")
}
return nil
}
func main() {
delay := 50 * time.Millisecond
var err error
for attempt := 0; attempt < 5; attempt++ {
err = flaky(attempt)
if err == nil {
fmt.Println("succeeded on attempt", attempt)
return
}
fmt.Printf("attempt %d failed, waiting %v\n", attempt, delay)
time.Sleep(delay)
delay *= 2
}
fmt.Println("gave up:", err)
}Уважение к контексту
Передайте context в цикл повторов и во время ожидания выполняйте выбор по ctx.Done(). Это позволяет отменившей операцию или превысившей время ожидания вызывающей стороне немедленно прекратить повторы.
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(delay):
}Различение ошибок
Не каждую ошибку следует повторять. Ошибка 400 «Неверный запрос» будет возникать снова и снова. Проверьте ошибку или код состояния и повторяйте запросы только при временных сбоях, например при истечении времени ожидания, коде 429 и кодах 5xx.
Размыкатели цепи
Если сбои продолжаются, размыкатель цепи на период охлаждения прекращает отправлять запросы вместо повторения каждого вызова. Он дополняет задержку перед повтором, защищая от явно недоступной зависимости.
Проверка знаний
Проверьте свои знания о задержке перед повтором.
Итоги
Вы изучили задержку перед повтором:
- Экспоненциальная задержка после каждого сбоя удваивается
- Случайный разброс предотвращает синхронные лавины повторов
- Ограничивайте задержку и число попыток
- Повторяйте только идемпотентные операции или запросы с повторяемыми ошибками
- Учитывайте контекст для отмены
Часто задаваемые вопросы
Урок «Отложенный повтор» бесплатный?
Да — полный текст урока «Отложенный повтор» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 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 — локальная установка не требуется.
Все уроки этого курса
- Концепция корзины токенов
- golang.org/x/time/rate
- Ограничение горутин
- Отложенный повтор