Go Daily Library 113: повторить попытку
Go Daily Library 113: повторить попытку

В микросервисной архитектуре обычно имеется множество небольших сервисов и большое количество RPC вызов,Но часто из-за таких причин, как тряска сети,вызывая сбой запроса,В настоящее время использование механизма повтора может повысить окончательную вероятность успеха запроса.,Уменьшите последствия сбоев,Сделайте работу системы более стабильной。retry-go Это относительно полная функция golang Повторите попытку библиотеки.

Установить

Язык кода:javascript
копировать
go get https://github.com/avast/retry-go

Быстрый в использовании

Использовать retry-go очень просто, просто используйте метод Do напрямую. Ниже приведен пример повтора запроса HTTP Get:

Язык кода:javascript
копировать
url := "http://example.com"
var body []byte

err := retry.Do(
	func() error {
		resp, err := http.Get(url)
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		body, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}

		return nil
	},
)

fmt.Println(body)

При вызове есть несколько дополнительных элементов конфигурации:

  • attempts Максимальное количество повторов
  • delay Время задержки повтора
  • maxDelay максимум Время задержки повтора,При выборе индексной стратегии отсрочки,Конфигурация ограничит время ожидания.
  • maxJitter Максимальное время ожидания для стратегии случайной отсрочки
  • onRetry Обратный вызов, выполняемый при каждой повторной попытке
  • retryIf Условное решение при повторной попытке
  • delayType Тип стратегии отсрочки
  • lastErrorOnly Возвращать ли только ошибку последней повторной попытки

Стратегия отсрочки BackOff

В случае некоторых временных ошибок, таких как дрожание сети и т. д., немедленная повторная попытка все равно может оказаться неудачной. Обычно вероятность успеха будет выше, если вы подождите некоторое время и повторите попытку, и эта стратегия также может сократить время повтора восходящего потока. Избегайте мгновенных всплесков трафика, вызванных одновременными повторными попытками. Метод принятия решения о том, как долго ждать перед повторной попыткой, называется стратегией отсрочки. retry-go реализует следующие стратегии отсрочки:

BackOffDelay

Язык кода:javascript
копировать
func BackOffDelay(n uint, _ error, config *Config) time.Duration

BackOffDelay обеспечивает экспоненциальную стратегию отсрочки. При непрерывных повторных попытках каждое время ожидания в два раза дольше предыдущего.

FixedDelay

Язык кода:javascript
копировать
func FixedDelay(_ uint, _ error, config *Config) time.Duration

Фиксированная задержка Ожидает фиксированного времени задержки при каждой повторной попытке.

RandomDelay

Язык кода:javascript
копировать
func RandomDelay(_ uint, _ error, config *Config) time.Duration

RandomDelay ожидает случайное время в пределах 0 — config.maxJitter перед повторной попыткой.

CombineDelay

Язык кода:javascript
копировать
func CombineDelay(delays ...DelayTypeFunc) DelayTypeFunc

JointDelay предоставляет возможность комбинировать несколько стратегий для реализации новой стратегии.

Стратегия отсрочки повтора по умолчанию представляет собой комбинацию BackOffDelay и RandomDelay, то есть добавление случайного времени с экспоненциальным увеличением.

Индивидуальная стратегия задержки

Ниже приведен официальный пример: если ответ на запрос имеет заголовок Retry-After, используйте это значение для ожидания. В других случаях задержите ожидание в соответствии с политикой BackOffDelay.

Язык кода:javascript
копировать
var _ error = (*RetriableError)(nil)

func test2(){
    var body []byte

    err := retry.Do(
        func() error {
            resp, err := http.Get("URL")

            if err == nil {
                defer func() {
                    if err := resp.Body.Close(); err != nil {
                        panic(err)
                    }
                }()
                body, err = ioutil.ReadAll(resp.Body)
                if resp.StatusCode != 200 {
                    err = fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
                    if resp.StatusCode == http.StatusTooManyRequests {
                        // check Retry-After header if it contains seconds to wait for the next retry
                        if retryAfter, e := strconv.ParseInt(resp.Header.Get("Retry-After"), 10, 32); e == nil {
                            // the server returns 0 to inform that the operation cannot be retried
                            if retryAfter <= 0 {
                                return retry.Unrecoverable(err)
                            }
                            return &RetriableError{
                                Err:        err,
                                RetryAfter: time.Duration(retryAfter) * time.Second,
                            }
                        }
                        // A real implementation should also try to http.Parse the retryAfter response header
                        // to conform with HTTP specification. Herein we know here that we return only seconds.
                    }
                }
            }

            return err
        },
        retry.DelayType(func(n uint, err error, config *retry.Config) time.Duration {
            fmt.Println("Server fails with: " + err.Error())
            if retriable, ok := err.(*RetriableError); ok {
                fmt.Printf("Client follows server recommendation to retry after %v\n", retriable.RetryAfter)
                return retriable.RetryAfter
            }
            // apply a default exponential back off strategy
            return retry.BackOffDelay(n, err, config)
        }),
    )

    fmt.Println("Server responds with: " + string(body))
}

Подвести итог

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

Reference

Команда ByteDance – Как изящно повторить попытку

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода