A shield with JWT segments and a green padlock, for offline licensing

Por qué construimos Qarote: una historia de saturación de colas

El mensaje llegó a las 2:47 de la madrugada. No era una alerta de PagerDuty — era un mensaje de Slack de un cliente.

“Oye, ¿tienen problemas ahora mismo? Nuestros trabajos no se han procesado en la última hora.”

Una hora.

Abrí el plugin de administración de RabbitMQ. El gráfico de profundidad de cola era una línea vertical. 847.000 mensajes. Nuestra cola principal de trabajos había estado llenándose, sin supervisión, durante sesenta y tres minutos. Dos consumidores estaban conectados. Ninguno procesaba nada.

Tenía cuatro pestañas abiertas en treinta segundos: el plugin de administración, Grafana, CloudWatch y un hilo de Slack donde mis compañeros intentaban entender lo mismo desde diferentes dashboards.

Nadie sabía qué había pasado.

Lo que mostraban las herramientas

El plugin de administración me dijo lo que ya sabía al ver el gráfico: la cola estaba profunda, la tasa de mensajes era cero y dos consumidores aparecían como conectados.

Lo que no podía decirme:

  • ¿Qué consumidores eran esos dos? ¿Eran los workers esperados, o conexiones zombie de un despliegue anterior?
  • ¿Por qué estaban conectados pero sin procesar? ¿Bloqueados en un mensaje? ¿Crashando silenciosamente? ¿Esperando un servicio downstream?
  • ¿Cuándo comenzó el backlog de cola? La resolución del gráfico era demasiado gruesa para identificar el momento exacto en que las cosas salieron mal — no podía saber si la acumulación empezó diez minutos atrás o dos horas atrás.
  • ¿Era una cola aislada o una cascada? Tenía quince colas. El plugin me mostraba una a la vez.
  • ¿Cómo eran los mensajes? Era imposible inspeccionar un solo mensaje sin escribir un consumidor desechable — lo que significaba que no podía confirmar si los mensajes en sí estaban malformados o si el problema venía de los consumidores.

Cambié a Grafana. Las métricas de Prometheus de RabbitMQ que habíamos configurado daban datos de series temporales para la profundidad de cola y el número de consumidores, pero el intervalo de scrape era de 60 segundos — los datos ya tenían un minuto de retraso. Y los dashboards estaban organizados por broker, no por lo que realmente necesitaba: una lista de colas que se comportaran anómalamente en ese momento.

Cuarenta minutos después del inicio del incidente, finalmente aislé la causa: un pool de conexiones a la base de datos agotado bajo carga. Los consumidores tomaban mensajes, fallaban silenciosamente en la primera llamada a la BD, hacían nack sin registrar el error correctamente y volvían a encolar — creando un bucle ajustado que, desde el plugin de administración, parecía “dos consumidores conectados, rendimiento cero.”

La solución tardó cinco minutos. El diagnóstico tardó cuarenta.

El problema real

He pensado mucho en ese incidente desde entonces.

El problema no era que tuviéramos malas herramientas. El plugin de administración es genuinamente útil para la visibilidad del día a día. Prometheus + Grafana es una pila de monitorización legítima. El problema era que ninguna de estas herramientas estaba diseñada para responder a la pregunta que realmente hacía a las 3 de la madrugada: ¿qué está mal, ahora mismo, y qué hago al respecto?

El plugin de administración muestra estado. Grafana muestra historial. Ninguno muestra causalidad.

Para diagnosticar correctamente un incidente de RabbitMQ, necesitas correlacionar cosas que viven en lugares diferentes: profundidad de cola con salud de consumidores, salud de consumidores con tasas de ack, tasas de ack con las colas específicas donde los consumidores están atascados. Necesitas ver qué consumidores están procesando realmente versus cuáles están conectados-pero-congelados. Necesitas ver si el backlog de una cola comenzó a crecer al mismo tiempo que cayó el número de consumidores, o antes — porque son incidentes diferentes.

Nada de eso se mostraba automáticamente. Había que ensamblarlo manualmente, pestaña por pestaña, durante un incidente.

La pila de monitorización estándar para un despliegue de RabbitMQ en producción en ese momento era:

  • Plugin de administración — interfaz web, útil para inspección manual
  • Exportador de Prometheus — convierte las métricas de RabbitMQ en endpoints scrapables
  • Alertmanager — enruta alertas basadas en métricas a Slack o PagerDuty
  • Grafana — dashboards para análisis de tendencias
  • Scripts personalizados — normalmente Python, normalmente verificando la profundidad de las DLQ

Cinco herramientas. Para un solo broker. Cada una requiriendo configuración, mantenimiento y alguien que sepa qué pestaña mirar cuando las cosas van mal.

Eso no es una pila de monitorización. Es arqueología.

Lo que queríamos en su lugar

Después del incidente, empecé a pensar en cómo sería una herramienta de monitorización de RabbitMQ diseñada específicamente para responder “¿qué está mal ahora mismo?” en lugar de “aquí están todas las métricas, buena suerte.”

Algunas cosas parecían innegociables:

Tasa de cambio, no solo profundidad. Una cola en 50.000 mensajes creciendo a +500/s es un despertador a las 3 de la madrugada en 90 minutos. La misma cola decreciendo a -1.000/s es saludable. La profundidad sola es un indicador rezagado. Necesitas velocidad para saber si te diriges hacia un incidente o te estás recuperando de uno.

La salud de los consumidores como señal de primer nivel. No solo “cuántos consumidores están conectados” sino “¿están procesando realmente?” Un consumidor conectado pero que no hace ack está roto. Esa distinción es invisible en la mayoría de las configuraciones de monitorización.

Un historial de cola que realmente sirva después del incidente. La retención nativa de RabbitMQ es corta y poco precisa. Lo que necesitaba esa noche era un gráfico de profundidad con resolución de 5 minutos y 7 días de retención — algo que mostrara exactamente cuándo empezó el backlog, no solo que actualmente era grande. Esa precisión cambia cómo se acota un incidente: ¿fuga lenta o caída repentina?

La capacidad de inspeccionar mensajes sin consumirlos. Esa noche no podía confirmar si los mensajes eran válidos sin escribir un consumidor desechable. Necesitaba poder inspeccionar la cola — leer cabeceras, verificar la estructura del payload — sin consumir un solo mensaje. Esa capacidad por sí sola habría reducido 15 minutos del diagnóstico.

Correlación automática de incidentes, no navegación manual entre pestañas. El diagnóstico de cuarenta minutos no fue cuarenta minutos de reflexión intensa. Fue cuarenta minutos ensamblando contexto que ya existía en tres herramientas diferentes. Una herramienta que correlaciona picos de backlog, caídas de consumidores y cambios en la tasa de mensajes en una sola línea de tiempo no hace magia — hace automáticamente la parte mecánica del diagnóstico de incidentes.

Alertas sobre indicadores adelantados, no solo rezagados. Una alerta que se dispara cuando tu cola llega a 500.000 mensajes confirma principalmente que ya estás en un incidente. Una alerta que se dispara cuando tu cola crece más rápido que tu tasa de vaciado — cuando tienes cinco minutos de margen — es realmente útil.

Un resumen de salud diario entregado en tu bandeja de entrada. No porque quiera revisar dashboards cada mañana, sino porque las pequeñas acumulaciones hay que detectarlas antes de que se conviertan en llamadas a las 3 de la madrugada. Un digest diario con tendencias de profundidad de cola, estado de consumidores y anomalías de las últimas 24 horas significa que nunca entras a un incidente sin contexto.

Cero Prometheus requerido. No porque Prometheus sea malo, sino porque montar una pila completa Prometheus + Grafana + Alertmanager solo para monitorizar un cluster de RabbitMQ es una inversión significativa para equipos que no la tienen ya.

Por qué lo construimos en lugar de parchear herramientas existentes

Examiné seriamente las opciones existentes. Hay plantillas de dashboards de Grafana para RabbitMQ. Hay plataformas APM SaaS con integraciones de RabbitMQ. Hay productos comerciales de monitorización de RabbitMQ.

Ninguno estaba construido desde la premisa de que lo más importante es: dime qué está mal, no solo qué está pasando.

Así que construimos Qarote.

Qarote es una herramienta de monitorización de RabbitMQ auto-hospedada que se conecta directamente a la API HTTP de administración — sin plugin de Prometheus, sin YAML, sin agentes que desplegar. Núcleo con licencia MIT, auto-hospedable en dos minutos con un solo comando Docker.

Esto es lo que habría pasado en ese incidente con Qarote funcionando:

  • Minuto 1: Bandera de consumidor-conectado-pero-sin-ack levantada. Qarote interroga cada 15 segundos — sin retraso de 60 segundos.
  • Minuto 1: Alerta de tasa de crecimiento de cola disparada. El backlog se aceleraba, no solo era profundo.
  • Minuto 2: El Motor de Diagnóstico de Incidentes correlacionó el pico de backlog, la caída de la tasa de ack de los consumidores y el pico de errores de la aplicación — misma ventana de 4 minutos, automáticamente. Sin cambiar de pestaña.
  • Minuto 5: Message Spy confirmó que los mensajes en la cola bloqueada eran estructuralmente válidos — payload intacto, cabeceras correctas. Los mensajes no eran el problema. Los consumidores sí.
  • Minuto 5: Acotado a BD o red. Corrección desplegada en el minuto 10.

Diez minutos, no cuarenta.

Y a la mañana siguiente, el Daily Digest habría incluido el incidente en el resumen de anomalías de las 24 horas — todo el equipo habría estado informado antes de abrir Slack, sin que nadie tuviera que escribir un email de retrospectiva.

Si esa misma cola hubiera estado acumulándose lentamente durante días antes del incidente — una fuga lenta en lugar de una caída repentina — el Historial de Colas lo habría mostrado: snapshots cada 5 minutos retenidos 7 días, graficables junto al número de consumidores y la tasa de publicación.


Si ejecutas RabbitMQ en producción y has tenido la experiencia de mirar el plugin de administración durante un incidente preguntándote qué está mal realmente, pruébalo. El nivel gratuito cubre todo lo que necesitas para empezar. La configuración toma unos dos minutos.

Si quieres ejecutarlo tú mismo, el núcleo es código abierto en GitHub.

Brice Tessier
Brice Tessier
CTO of Qarote

Building agent-native RabbitMQ diagnosis. Previously spent too many on-call nights staring at queue charts — which is roughly why Qarote exists.

Try it on your own broker.

Connect in under two minutes, wire your agent, and ask it what's wrong.