Colas de mensajes
Colas de mensajes: reintentos, letras muertas y duplicados
Patrones para que un mensaje fallido no arrastre al resto del sistema
Cuando un consumidor falla, la cola puede convertirse en un amplificador de errores si no hay una política clara de reintentos. Lo vimos varias veces en producción: un servicio que responde lento por una dependencia externa empieza a devolver timeouts, el broker reencola los mensajes, el consumidor se satura, y en pocos minutos la cola crece más rápido de lo que cualquier worker puede procesar. El problema no es el fallo original, es la ausencia de un plan para cuando algo falla.
Este texto compara enfoques de backoff, colas de mensajes muertos y deduplicación por clave de idempotencia, con ejemplos de configuración en brokers conocidos. La idea es simple: cada mensaje que no se puede procesar tiene que tener un destino decidido de antemano, no improvisado durante el incidente.
Los reintentos infinitos esconden fallos de diseño. Si un mensaje lleva horas rebotando entre el broker y el consumidor, nadie está mirando por qué falla: solo se está evitando reconocer que ese mensaje no se va a procesar con el código actual. Un backoff exponencial con techo acotado y un número máximo de intentos deja el problema a la vista. A partir de ahí, la decisión es binaria: el mensaje pasa a una cola de mensajes muertos o se descarta con registro.
Medir la antigüedad de los mensajes pendientes es más útil que mirar el tamaño de la cola. Una cola con diez mil mensajes que se drenan en segundos está sana; una con doscientos mensajes que llevan una hora sin moverse está rota. Ese indicador, junto con la tasa de mensajes que terminan en la cola muerta, permite detectar acumulación antes de que el sistema se caiga.
La deduplicación por clave de idempotencia resuelve el otro extremo: reintentos que sí funcionan pero generan duplicados. Si el consumidor procesa el mismo mensaje dos veces porque el ack se perdió, el resultado depende del negocio. Para operaciones no idempotentes conviene guardar la clave procesada con una ventana de retención alineada al tiempo máximo de reintento. Sin esa ventana, la deduplicación no protege nada.
El cierre incluye criterios para decidir cuándo descartar un mensaje y cuándo alertar a un humano. Un mensaje con error de validación se descarta y se registra. Un mensaje que falla por una dependencia caída se reintenta. Un mensaje que lleva demasiado tiempo en la cola muerta sin que nadie lo revise es una alerta, no un pendiente.
Si querés ver cómo aplicamos estas políticas en servicios reales, podés revisar los servicios que documentamos o escribirnos desde la página de contacto. También hay más notas técnicas en el blog.