Go Academy · Lezione

Backoff e retry

Riprovare con backoff

Lezione 4 di 413 passaggi

Backoff e retry è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

Perché ritentare

Gli errori temporanei, i timeout, le connessioni interrotte e brevi risposte 503 spesso si risolvono al secondo tentativo. Ritentare rende affidabile un'operazione instabile senza disturbare il chiamante.

I nuovi tentativi ingenui sono pericolosi

Ritentare immediatamente in un ciclo serrato sovraccarica un servizio già in difficoltà e può causare una raffica di nuovi tentativi. Servono ritardi tra i tentativi, e questi ritardi devono aumentare.

Backoff esponenziale

Il backoff esponenziale raddoppia l'attesa dopo ogni errore: 100ms, 200ms, 400ms, 800ms. In questo modo il servizio a valle ha il tempo di riprendersi.

delay := 100 * time.Millisecond
for attempt := 0; attempt < 5; attempt++ {
    // try, on failure:
    time.Sleep(delay)
    delay *= 2
}

Aggiungere il jitter

Se molti client applicano il backoff in sincronia, ritentano nello stesso momento, causando un effetto thundering herd. Il jitter rende casuale ogni ritardo in misura limitata, distribuendo nel tempo i nuovi tentativi.

jitter := time.Duration(rand.Int63n(int64(delay) / 2))
time.Sleep(delay + jitter)

Limitare il ritardo

La crescita esponenziale raggiunge rapidamente valori enormi. Imposti un ritardo massimo, così non dovrà attendere minuti tra un tentativo e l'altro.

if delay > 2*time.Second {
    delay = 2 * time.Second
}

Limitare i tentativi

Limiti sempre il numero di tentativi. Dopo aver raggiunto il limite, restituisca l'ultimo errore, lasciando al chiamante la decisione sul da farsi invece di ritentare all'infinito.

Ritentare solo operazioni idempotenti

Ritentare è sicuro solo quando l'operazione può essere eseguita due volte senza conseguenze indesiderate. Un GET è idempotente; un POST non idempotente che addebita un pagamento non dovrebbe essere ritentato alla cieca. Quando necessario, utilizzi chiavi di idempotenza.

Un retry completo con backoff

Questo programma ritenta una funzione che fallisce due volte e poi riesce, raddoppiando ogni volta il ritardo. Utilizza solo la libreria standard.

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)
}

Rispettare context

Passi un context al ciclo di retry e utilizzi select su ctx.Done() durante l'attesa. In questo modo un chiamante che ha annullato l'operazione o il cui timeout è scaduto può interrompere immediatamente i nuovi tentativi.

select {
case <-ctx.Done():
    return ctx.Err()
case <-time.After(delay):
}

Distinguere gli errori

Non tutti gli errori consentono un nuovo tentativo. Una risposta 400 Bad Request fallirà sempre. Esamini l'errore o il codice di stato e ritenti solo in caso di classi temporanee, come timeout, 429 e 5xx.

Circuit breaker

Quando gli errori persistono, un circuit breaker smette di inviare richieste per un periodo di raffreddamento invece di ritentare ogni chiamata. Completa il backoff proteggendo una dipendenza chiaramente non disponibile.

Verifica rapida

Verifichi la Sua conoscenza del backoff.

Riepilogo

Ha imparato a usare backoff e retry:

  • Il backoff esponenziale raddoppia il ritardo dopo ogni errore
  • Il jitter previene le raffiche di nuovi tentativi sincronizzati
  • Limiti il ritardo e il numero di tentativi
  • Ritenti solo errori idempotenti o ritentabili
  • Rispetti context per consentire l'annullamento
Gratis per iniziare

Impara Go con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
51
Lezioni
203

Domande Frequenti

La lezione «Backoff e retry» è gratuita?

Sì — il testo completo di «Backoff e retry» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «Backoff e retry»?

Riprovare con backoff Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Backoff e retry»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Concetto del token bucket
  2. golang.org/x/time/rate
  3. Limitare le goroutine
  4. Backoff e retry
← Torna a Go Academy