Voltar ao código Java

Reintentar una llamada que falla, esperando cada vez más

Reintentos con espera exponencial y un poco de azar, para no golpear a un servicio que ya está caído.

Este post ainda não está no seu idioma; você o vê em espanhol. O código é o mesmo.

O problema

Una llamada a un servicio externo falla de vez en cuando. Reintentar de inmediato y sin límite empeora la caída; no reintentar convierte un parpadeo en un error para el usuario.

Java
import java.util.concurrent.Callable;

public class Reintento {
    public static <T> T conBackoff(Callable<T> tarea, int intentos) throws Exception {
        long espera = 200;                       // milisegundos
        for (int i = 1; ; i++) {
            try {
                return tarea.call();
            } catch (Exception e) {
                if (i >= intentos) throw e;      // se acabaron: que suba el error real
                System.out.printf("Intento %d falló (%s). Espero %d ms%n", i, e.getMessage(), espera);
                Thread.sleep(espera + (long) (Math.random() * 100));
                espera *= 2;
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String r = conBackoff(() -> {
            if (Math.random() < 0.7) throw new RuntimeException("servicio caído");
            return "respuesta";
        }, 5);
        System.out.println(r);
    }
}

Por que está escrito assim

  1. La espera se duplica en cada intento: 200, 400, 800 ms. Le da aire al servicio para recuperarse.
  2. El azar sumado (jitter) evita que cien clientes reintenten todos en el mismo milisegundo.
  3. Cuando se agotan los intentos se relanza la excepción original, no una genérica: el que investiga ve la causa real.
  4. El método es genérico: sirve para cualquier tarea que devuelva algo.
Como testar

Guardalo como Reintento.java y corré: java Reintento.java. Cada corrida falla una cantidad distinta de veces.

Atenção

Solo se reintenta lo que es seguro repetir. Reintentar un cobro o un envío de correo sin una clave de idempotencia duplica la operación.

Adapte ao seu caso com IA

O botão copia este prompt com o código colado abaixo. Substitua os colchetes pelo que é seu e cole no ChatGPT, Claude, Gemini ou Copilot.

O prompt
Tengo este reintento con backoff en Java. Adaptalo para que solo reintente ante estas excepciones: [EXCEPCIONES REINTENTABLES], tenga un tope de espera de [TOPE] segundos y registre cada intento con [MI LIBRERÍA DE LOGS]. Es para llamar a [QUÉ SERVICIO]. Decime también si esa operación es segura de reintentar y qué haría falta si no lo es.

Exemplo escrito e revisado à mão.

Compartilhar

Comentários

Ainda não há comentários. O primeiro pode ser o seu.

Apenas texto, sem links. Não pedimos e-mail. Os comentários são revisados antes de serem publicados.

Adaptou para algo seu?

Me conte o que resolveu com isto, ou o que faltou.

Continue testando

Mais código

Ver todos
Darinel Ortega Online · respondo ao longo do dia
Hoje
Olá. Aqui eu não vendo nada: isto é para trocar conhecimento sobre tecnologia.
Escreva o que quiser — pode mandar texto, imagens ou documentos. As mensagens chegam ao meu console e eu respondo por lá.
Você está escrevendo fora do horário. Eu leio assim que o dia começar.

Conversa aberta para compartilhar conhecimento. As mensagens chegam ao meu console e eu respondo por lá.

Vamos marcar uma conversa

Escolha o dia e a hora que funcionem para você. Trinta minutos, sem discurso comercial.

Videochamada

Para uma videochamada, peça por aqui que eu te mando o link da sessão.