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.
The problem
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.
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);
}
}
Why it is written this way
- La espera se duplica en cada intento: 200, 400, 800 ms. Le da aire al servicio para recuperarse.
- El azar sumado (jitter) evita que cien clientes reintenten todos en el mismo milisegundo.
- Cuando se agotan los intentos se relanza la excepción original, no una genérica: el que investiga ve la causa real.
- El método es genérico: sirve para cualquier tarea que devuelva algo.
Guardalo como Reintento.java y corré: java Reintento.java. Cada corrida falla una cantidad distinta de veces.
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.
Adapt it to your case with AI
The button copies this prompt with the code pasted below it. Replace the brackets with your own details and paste it into ChatGPT, Claude, Gemini or Copilot.
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.
Example written and reviewed by hand.
Comments
No comments yet. Yours can be the first.
Did you adapt it to something of yours?
Tell me what you solved with it, or what it was missing.