0Pricing
Go Academy · Lección

Retirada progresiva y reintento

Reintente con backoff

Retirada progresiva y reintento es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.

Por qué reintentar

Los fallos transitorios, los tiempos de espera agotados, las conexiones interrumpidas y los breves errores 503 suelen resolverse en un segundo intento. Reintentar convierte una operación inestable en una operación fiable sin molestar a quien la invoca.

Reintentar ingenuamente es peligroso

Reintentar de inmediato en un bucle rápido sobrecarga un servicio que ya tiene problemas y puede provocar una avalancha de reintentos. Necesitamos introducir esperas entre los intentos, y esas esperas deben aumentar.

Backoff exponencial

El backoff exponencial duplica la espera después de cada fallo: 100 ms, 200 ms, 400 ms, 800 ms. Esto da tiempo al servicio descendente para recuperarse.

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

Añadir jitter

Si muchos clientes aplican el backoff al mismo ritmo, reintentan en el mismo momento y provocan una estampida de solicitudes. El jitter aleatoriza ligeramente cada espera para distribuir los reintentos a lo largo del tiempo.

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

Limitar el retraso

El crecimiento exponencial aumenta muy rápido. Establezca un retraso máximo para no tener que esperar minutos entre los intentos.

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

Limitar los intentos

Limite siempre el número de intentos. Después de alcanzar el límite, devuelva el último error para que quien invoca la operación decida qué hacer en lugar de reintentar indefinidamente.

Reintentar solo operaciones idempotentes

Reintentar es seguro únicamente cuando la operación puede ejecutarse dos veces sin causar daños. Un GET es idempotente; un POST no idempotente que cobre una tarjeta no debe reintentarse a ciegas. Use claves de idempotencia cuando sea necesario.

Un reintento completo con backoff

Este programa reintenta una función que falla dos veces y después tiene éxito, duplicando el retraso cada vez. Solo utiliza la biblioteca estándar.

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

Respetar el contexto

Pase un context al bucle de reintento y use select sobre ctx.Done() mientras espera. Esto permite que quien invoca la operación cancele o detenga por tiempo de espera los reintentos de inmediato.

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

Distinguir errores

No todos los errores se pueden reintentar. Una solicitud 400 Bad Request fallará siempre. Inspeccione el error o el código de estado y reintente únicamente ante clases transitorias, como tiempos de espera agotados, 429 y errores 5xx.

Circuit breakers

Cuando los fallos persisten, un circuit breaker deja de enviar solicitudes durante un periodo de enfriamiento en lugar de reintentar cada llamada. Complementa el backoff al proteger una dependencia que está claramente caída.

Comprobación rápida

Compruebe sus conocimientos sobre el backoff.

Repaso

Ha aprendido sobre backoff y reintentos:

  • El backoff exponencial duplica el retraso después de cada fallo
  • El jitter evita las avalanchas de reintentos sincronizados
  • Limite el retraso y el número de intentos
  • Reintente solo errores idempotentes o que admitan reintentos
  • Respete el contexto para permitir la cancelación

Preguntas frecuentes

¿La lección «Retirada progresiva y reintento» es gratis?

Sí — el texto completo de «Retirada progresiva y reintento» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Retirada progresiva y reintento»?

Reintente con backoff Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Go Academy?

No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Retirada progresiva y reintento»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Go Academy?

Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Concepto del token bucket
  2. golang.org/x/time/rate
  3. Limitación de goroutines
  4. Retirada progresiva y reintento
← Volver a Go Academy