0Pricing
Go Academy · Aula

Recuo e nova tentativa

Tente novamente com recuo

Recuo e nova tentativa é uma aula grátis de Go Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Go Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Go Academy inclui 4 aulas no total.

Por que repetir

Falhas transitórias, tempos limite, conexões interrompidas e breves respostas 503 costumam funcionar em uma segunda tentativa. Repetir transforma uma operação flaky em uma operação confiável sem incomodar quem a chamou.

A repetição ingênua é perigosa

Repetir imediatamente em um laço apertado sobrecarrega um serviço em dificuldade e pode causar uma tempestade de repetições. Precisamos de intervalos entre as tentativas, e esses intervalos devem aumentar.

Espera exponencial

A espera exponencial duplica o tempo de espera após cada falha: 100ms, 200ms, 400ms, 800ms. Isso dá ao serviço dependente tempo para se recuperar.

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

Adicionando variação aleatória

Se muitos clientes aumentarem o tempo de espera em sincronia, eles tentarão novamente no mesmo momento, criando uma avalanche de solicitações. A variação aleatória muda ligeiramente cada intervalo para distribuir as tentativas ao longo do tempo.

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

Limitando o atraso

O crescimento exponencial aumenta rapidamente. Limite o atraso a um valor máximo para não esperar minutos entre as tentativas.

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

Limitando as tentativas

Sempre limite o número de tentativas. Depois de atingir o limite, retorne o último erro para que quem chamou decida o que fazer, em vez de repetir para sempre.

Repita apenas operações idempotentes

Repetir é seguro somente quando a operação pode ser executada duas vezes sem causar danos. Um GET é idempotente; um POST não idempotente que cobra um cartão não deve ser repetido cegamente. Use chaves de idempotência quando necessário.

Uma repetição completa com espera exponencial

Este programa repete uma função que falha duas vezes e depois tem sucesso, duplicando o atraso a cada tentativa. Ele usa somente a biblioteca padrão.

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

Respeitando o contexto

Passe um context ao laço de repetição e use select com ctx.Done() durante a espera. Assim, quem chamou pode interromper imediatamente as repetições quando a operação for cancelada ou exceder o tempo limite.

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

Diferenciando erros

Nem todo erro pode ser repetido. Uma resposta 400 Solicitação inválida falhará para sempre. Inspecione o erro ou o código de status e repita somente em classes transitórias, como tempos limite, 429 e 5xx.

Disjuntores

Quando as falhas persistem, um disjuntor para de enviar solicitações durante um período de resfriamento, em vez de repetir cada chamada. Ele complementa a espera exponencial ao proteger contra uma dependência claramente indisponível.

Verificação rápida

Teste seus conhecimentos sobre espera exponencial.

Recapitulação

Você aprendeu sobre espera exponencial e repetição:

  • A espera exponencial duplica o atraso a cada falha
  • A variação aleatória evita tempestades de repetições sincronizadas
  • Limite o atraso e o número de tentativas
  • Repita somente operações idempotentes ou erros passíveis de repetição
  • Respeite o contexto para permitir o cancelamento

Perguntas Frequentes

A aula “Recuo e nova tentativa” é grátis?

Sim — o texto completo de “Recuo e nova tentativa” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Go Academy, atualize para CoddyKit PRO. O curso de Go Academy inclui 4 aulas no total.

O que vou aprender em “Recuo e nova tentativa”?

Tente novamente com recuo Você pratica Go Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Go Academy?

Nenhuma experiência prévia é necessária. Go Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Recuo e nova tentativa”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Go Academy?

Sim. Cada aula de Go Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Conceito do balde de tokens
  2. golang.org/x/time/rate
  3. Limitação de goroutines
  4. Recuo e nova tentativa
← Voltar para Go Academy