Solución de problemas en RabbitMQ: Diagnóstico de colas y mensajes con comandos

Domina la utilidad de línea de comandos `rabbitmqctl` para solucionar problemas rápidamente en RabbitMQ. Esta guía proporciona comandos prácticos y accionables para diagnosticar problemas comunes como acumulaciones excesivas en colas, mensajes atascados, conectividad cero de consumidores y enlaces de intercambio incorrectos. Aprende diagnósticos esenciales para restaurar el flujo de mensajes rápidamente sin depender únicamente de la interfaz de usuario.

Solución de problemas en RabbitMQ: Diagnóstico de colas y mensajes con comandos

Cuando una cola de RabbitMQ parece atascada, el peor primer movimiento suele ser purgarla. El segundo peor movimiento es reiniciar el broker y esperar que el problema se resuelva. La mayoría de los problemas de colas dejan un rastro: mensajes listos, mensajes no confirmados, consumidores faltantes, publicadores bloqueados, mensajes no enrutables, una cola de mensajes muertos que se llena silenciosamente o un consumidor que está conectado pero no confirma nada.

Esta guía utiliza comandos de RabbitMQ para reducir el problema desde la terminal. Me apoyo en rabbitmqctl para el estado del lado del broker y rabbitmqadmin cuando necesitas operaciones de la API de gestión, como muestrear un mensaje de forma segura. Los ejemplos asumen el host virtual predeterminado a menos que se muestre una opción -p <vhost>. En sistemas reales, incluye siempre el vhost; muchos diagnósticos falsos ocurren porque alguien verifica / mientras la aplicación usa payments o prod.

Entendiendo rabbitmqctl

El comando rabbitmqctl actúa como la interfaz de línea de comandos (CLI) para interactuar con la capa de gestión de RabbitMQ. Te permite gestionar usuarios, permisos, intercambios, colas, enlaces y, lo más importante para la solución de problemas, examinar las estadísticas de tiempo de ejecución del broker.

Nota sobre la ejecución: La mayoría de los comandos requieren privilegios de root o que el usuario que ejecuta el comando sea miembro del grupo rabbitmq, o puede que necesites usar sudo.

Diagnosticando acumulaciones en colas y mensajes atascados

Uno de los problemas más comunes es una cola en crecimiento, lo que indica que los mensajes se están produciendo más rápido de lo que se están consumiendo, o que los consumidores han dejado de procesar.

Comienza con la cola, pero pide las columnas correctas

La salida predeterminada de list_queues es demasiado escasa para la solución de problemas. Pide las columnas que separan "esperando ser entregado" de "entregado pero no confirmado".

rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged messages consumers state

Léelo así:

Síntoma Significado probable
messages_ready creciendo, consumers es 0 No hay un consumidor activo suscrito a la cola. Verifica despliegues, credenciales, vhost y nombre de la cola.
messages_ready creciendo, consumidores presentes Los consumidores son demasiado lentos, están bloqueados o el prefetch es demasiado bajo para la carga de trabajo.
messages_unacknowledged alto y estable Los consumidores recibieron mensajes pero no los están confirmando. Busca manejadores atascados o un valor de prefetch demasiado alto.
state no es running La cola puede no estar disponible, estar sincronizándose o afectada por un problema de nodo. Verifica el estado del clúster y del líder de la cola.

Para colas de quórum, agrega las columnas de líder y membresía:

rabbitmqctl -p / list_queues name type leader members online messages_ready messages_unacknowledged consumers state

Eso importa porque una cola puede tener consumidores saludables en un nodo mientras el líder está en otro lugar, o una cola de quórum puede estar esperando que suficientes miembros se conecten.

Si la lista es larga, filtra con herramientas estándar del shell:

rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged consumers state \
  | awk '$2 > 0 || $3 > 0 || $4 == 0'

Verifica si el broker está bloqueando a los publicadores

rabbitmqctl status
rabbitmq-diagnostics alarms

Las alarmas de memoria y disco no significan que la cola esté mal configurada, pero explican muchos incidentes de "nada se mueve". Cuando RabbitMQ activa una alarma de memoria o espacio libre en disco, puede bloquear las conexiones de publicación. Los consumidores aún pueden drenar mensajes, por lo que el síntoma visible puede ser desigual: algunas colas se reducen, otras dejan de recibir nuevo trabajo y los publicadores agotan el tiempo de espera.

También verifica los oyentes y la salud del nodo:

rabbitmq-diagnostics ping
rabbitmq-diagnostics listeners
rabbitmq-diagnostics check_running
rabbitmq-diagnostics check_local_alarms

Inspecciona consumidores sin adivinar

list_connections te dice quién está conectado. list_channels te dice si esas conexiones abrieron canales y cuánto trabajo están manejando.

rabbitmqctl list_connections name user peer_host peer_port state channels recv_oct send_oct
rabbitmqctl list_channels connection name number consumer_count messages_unacknowledged prefetch_count state

Los patrones útiles son simples:

  • Sin conexión del host esperado: la aplicación está caída, no puede resolver el broker, no puede autenticarse o se está conectando a otro entorno.
  • La conexión existe, pero no hay canales: el cliente se conectó y luego falló antes de declarar o consumir.
  • Los canales existen, pero consumer_count es 0: la aplicación puede estar solo publicando, o la suscripción del consumidor falló.
  • messages_unacknowledged es alto en un canal: ese consumidor tiene trabajo en memoria y no está devolviendo confirmaciones rápidamente.

Si usas conexiones nombradas, incluye connection_name en la configuración de tu cliente. Una línea como 10.42.8.17:52344 -> 10.42.1.20:5672 es menos útil que billing-worker-7.

Verifica los enlaces antes de culpar a los consumidores

Cuando una cola está vacía pero la aplicación dice que publicó mensajes, el enrutamiento es el siguiente lugar para mirar.

rabbitmqctl -p / list_exchanges name type durable auto_delete internal arguments
rabbitmqctl -p / list_bindings source_name source_kind destination_name destination_kind routing_key arguments

Un intercambio directo requiere una coincidencia exacta de la clave de enrutamiento. Un intercambio de tema usa * para una palabra y # para cero o más palabras. Un intercambio fanout ignora las claves de enrutamiento. Si el intercambio no tiene un enlace coincidente y no tiene un intercambio alternativo, el mensaje no se puede enrutar. No está esperando en secreto en algún lugar.

Para la confirmación del lado del publicador, usa la publicación obligatoria y maneja los mensajes devueltos en el cliente. En el lado del broker, la interfaz de usuario de gestión y las métricas suelen ser mejores que rabbitmqctl para las tasas, pero list_bindings es suficiente para detectar los errores comunes: vhost incorrecto, intercambio incorrecto, clave de enrutamiento mal escrita o una cola enlazada al intercambio antiguo después de un despliegue.

Muestrea un mensaje de forma segura

No hay un comando general rabbitmqctl queue_get en RabbitMQ moderno. Usa el plugin de gestión a través de rabbitmqadmin o la API HTTP. Hazlo con cuidado: dependiendo del modo de confirmación, obtener mensajes puede eliminarlos o reencolarlos.

rabbitmqadmin -V / get queue=orders.pending count=3 ackmode=ack_requeue_true

Úsalo para responder preguntas específicas: ¿el payload es JSON válido?, ¿el tipo de mensaje es el que espera el consumidor?, ¿falta un encabezado requerido?, ¿la clave de enrutamiento es la que dijo el equipo productor? No lo uses como una herramienta de inspección masiva en una cola de producción ocupada.

Busca movimiento de mensajes muertos

El procesamiento retrasado a menudo se manifiesta como una cola de mensajes muertos que crece silenciosamente.

rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged arguments policy
rabbitmqctl -p / list_bindings source_name destination_name routing_key arguments \
  | grep -E 'dead|dlx|retry|parking'

Los argumentos de cola como x-dead-letter-exchange, x-dead-letter-routing-key, x-message-ttl, x-max-length y x-overflow cambian a dónde van los mensajes cuando expiran, son rechazados o alcanzan los límites de longitud. Si la aplicación reintenta mediante mensajes muertos a través de colas de retardo, un enlace incorrecto puede crear un bucle. El síntoma parece "mensajes retrasados", pero el problema real es que los mensajes están circulando entre colas en lugar de llegar a una cola de procesamiento final o a una cola de estacionamiento.

Una secuencia de comandos práctica

Cuando alguien reporta "los pedidos están atascados", normalmente ejecuto esta secuencia:

rabbitmq-diagnostics ping
rabbitmq-diagnostics check_local_alarms
rabbitmqctl -p orders list_queues name type messages_ready messages_unacknowledged consumers state
rabbitmqctl list_connections name user peer_host state channels
rabbitmqctl list_channels connection consumer_count messages_unacknowledged prefetch_count state
rabbitmqctl -p orders list_bindings source_name destination_name routing_key arguments

Si messages_ready es alto y consumers es cero, ve al despliegue del consumidor. Si messages_unacknowledged es alto, ve a los registros del consumidor y a la configuración de prefetch. Si la cola está vacía pero los publicadores reportan éxito, inspecciona los enlaces y las confirmaciones del publicador. Si las alarmas están activas, soluciona la presión de recursos del broker antes de perseguir la lógica de la aplicación. Esto mantiene la investigación basada en lo que el broker está haciendo realmente.