RabbitMQ es un broker de mensajes que implementa AMQP 0-9-1 y permite que distintas partes de una aplicación se comuniquen de forma asíncrona a través de colas. En este tutorial instalarás RabbitMQ y la versión de Erlang que necesita desde los repositorios oficiales del equipo de RabbitMQ en Ubuntu 24.04, crearás un host virtual y usuarios con permisos mínimos, activarás la consola de gestión y enviarás y consumirás mensajes desde Python usando un exchange y colas quorum.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM.
- Un usuario no root con privilegios
sudo. - UFW activo con SSH permitido.
- Conocer los conceptos básicos de productor, consumidor y cola.
Paso 1: Añadir los repositorios oficiales de RabbitMQ y Erlang
Ubuntu incluye un paquete rabbitmq-server, pero suele ser una versión antigua. El equipo de RabbitMQ publica sus propios repositorios con la última versión del servidor y un Erlang compatible con ella.
Instala las herramientas necesarias:
sudo apt update
sudo apt install curl gnupg apt-transport-https
Descarga la clave de firma del equipo de RabbitMQ en /etc/apt/keyrings:
sudo install -m 0755 -d /etc/apt/keyrings
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor -o /etc/apt/keyrings/com.rabbitmq.team.gpg
Crea el archivo de repositorios para Ubuntu 24.04 (noble):
sudo nano /etc/apt/sources.list.d/rabbitmq.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-erlang/ubuntu/noble noble main
deb [arch=amd64 signed-by=/etc/apt/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-server/ubuntu/noble noble main
Actualiza el índice de paquetes:
sudo apt update
La salida debe incluir líneas Get o Hit para deb1.rabbitmq.com sin errores de firma.
Notaestos repositorios publican paquetes para
amd64. En servidores arm64 instalarabbitmq-serverdesde los repositorios de Ubuntu o usa la imagen oficial de Docker.
Paso 2: Instalar Erlang y RabbitMQ
Instala los paquetes de Erlang que RabbitMQ necesita. Instalarlos explícitamente evita que apt mezcle versiones de Erlang de Ubuntu y del repositorio de RabbitMQ:
sudo apt install erlang-base \
erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
erlang-runtime-tools erlang-snmp erlang-ssl \
erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
Instala el servidor:
sudo apt install rabbitmq-server --fix-missing
El paquete crea el usuario de sistema rabbitmq, habilita el servicio y lo arranca. Compruébalo:
systemctl status rabbitmq-server --no-pager
● rabbitmq-server.service - RabbitMQ broker
Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; enabled; preset: enabled)
Active: active (running)
Consulta el estado del nodo y las versiones instaladas:
sudo rabbitmq-diagnostics status | head -n 20
La salida muestra la versión de RabbitMQ, la de Erlang, el uso de memoria y los listeners activos (AMQP en el puerto 5672).
Paso 3: Ajustar la configuración básica
RabbitMQ lee /etc/rabbitmq/rabbitmq.conf, que no existe tras la instalación. Créalo con los ajustes más relevantes:
sudo nano /etc/rabbitmq/rabbitmq.conf
# Puerto AMQP
listeners.tcp.default = 5672
# Consola de gestión (se activa en el paso 5)
management.tcp.port = 15672
# Bloquea a los publicadores cuando RabbitMQ usa el 60 % de la RAM
vm_memory_high_watermark.relative = 0.6
# Bloquea a los publicadores si quedan menos de 2 GB libres en disco
disk_free_limit.absolute = 2GB
# El usuario guest solo puede conectarse desde localhost (valor por defecto, explícito)
loopback_users.guest = true
Reinicia el servicio y confirma que arranca sin errores:
sudo systemctl restart rabbitmq-server
sudo rabbitmq-diagnostics check_running
Checking if RabbitMQ is running on node rabbit@your_hostname ...
RabbitMQ on node rabbit@your_hostname is fully booted and running
Si el servicio no arranca, revisa los errores con sudo journalctl -u rabbitmq-server -n 50. Los logs detallados están en /var/log/rabbitmq/.
Paso 4: Crear un host virtual y usuarios
Los hosts virtuales (vhosts) aíslan colas, exchanges y permisos. Crea uno para tu aplicación:
sudo rabbitmqctl add_vhost app
Crea un usuario administrador para la consola y otro para la aplicación. Sustituye las contraseñas por unas robustas:
sudo rabbitmqctl add_user admin 'your_admin_password'
sudo rabbitmqctl set_user_tags admin administrator
sudo rabbitmqctl set_permissions -p app admin ".*" ".*" ".*"
sudo rabbitmqctl add_user app_user 'your_app_password'
sudo rabbitmqctl set_permissions -p app app_user "^orders.*" "^orders.*" "^orders.*"
Los tres patrones de set_permissions son, en orden, los permisos de configurar, escribir y leer. Con ^orders.*, app_user solo puede declarar y usar exchanges y colas cuyo nombre empiece por orders.
Elimina el usuario guest, que tiene una contraseña conocida:
sudo rabbitmqctl delete_user guest
Verifica usuarios y permisos:
sudo rabbitmqctl list_users
sudo rabbitmqctl list_permissions -p app
Listing permissions for vhost "app" ...
user configure write read
admin .* .* .*
app_user ^orders.* ^orders.* ^orders.*
Paso 5: Activar la consola de gestión
El plugin de gestión añade una interfaz web y una API HTTP en el puerto 15672:
sudo rabbitmq-plugins enable rabbitmq_management
No expongas la consola a Internet. Accede a ella a través de un túnel SSH desde tu equipo:
ssh -L 15672:127.0.0.1:15672 your_user@your_server_ip
Con el túnel abierto, visita http://localhost:15672 en tu navegador e inicia sesión con el usuario admin. Verás la vista general con el nodo, las conexiones y las colas.
Abre el puerto AMQP solo a los servidores de aplicación que lo necesiten. Sustituye app_server_ip por la IP (idealmente privada) de cada cliente:
sudo ufw allow from app_server_ip to any port 5672 proto tcp
sudo ufw status
AdvertenciaAMQP en el puerto 5672 viaja sin cifrar. Si los clientes se conectan por Internet y no por una red privada, configura TLS (puerto 5671) antes de enviar datos sensibles.
Paso 6: Publicar y consumir mensajes con Python
Vas a crear un exchange de tipo topic llamado orders, dos colas y sus bindings, y a enviar mensajes con la librería pika, disponible como paquete de Ubuntu:
sudo apt install python3-pika
Crea el script del productor:
nano ~/producer.py
#!/usr/bin/env python3
import json
import pika
credentials = pika.PlainCredentials("app_user", "your_app_password")
params = pika.ConnectionParameters("127.0.0.1", 5672, "app", credentials)
connection = pika.BlockingConnection(params)
channel = connection.channel()
# Exchange de tipo topic que sobrevive a reinicios
channel.exchange_declare(exchange="orders", exchange_type="topic", durable=True)
# Colas quorum: replicadas y pensadas para no perder mensajes
for queue, key in (("orders.created", "order.created"), ("orders.all", "order.#")):
channel.queue_declare(queue=queue, durable=True, arguments={"x-queue-type": "quorum"})
channel.queue_bind(queue=queue, exchange="orders", routing_key=key)
# Confirmaciones del broker: basic_publish falla si el mensaje no se acepta
channel.confirm_delivery()
for order_id in range(1, 6):
body = json.dumps({"order_id": order_id, "total": 19.90})
channel.basic_publish(
exchange="orders",
routing_key="order.created",
body=body,
properties=pika.BasicProperties(delivery_mode=2, # mensaje persistente
content_type="application/json"),
)
print(f"Enviado pedido {order_id}")
connection.close()
Crea el consumidor, que confirma cada mensaje solo después de procesarlo:
nano ~/consumer.py
#!/usr/bin/env python3
import json
import pika
credentials = pika.PlainCredentials("app_user", "your_app_password")
params = pika.ConnectionParameters("127.0.0.1", 5672, "app", credentials)
connection = pika.BlockingConnection(params)
channel = connection.channel()
# Como máximo 10 mensajes sin confirmar por consumidor
channel.basic_qos(prefetch_count=10)
def handle(ch, method, properties, body):
order = json.loads(body)
print(f"Procesando pedido {order['order_id']}")
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume(queue="orders.created", on_message_callback=handle)
print("Esperando mensajes. Pulsa Ctrl+C para salir.")
try:
channel.start_consuming()
except KeyboardInterrupt:
channel.stop_consuming()
connection.close()
Ejecuta el productor:
python3 ~/producer.py
Enviado pedido 1
Enviado pedido 2
Enviado pedido 3
Enviado pedido 4
Enviado pedido 5
Comprueba que los mensajes están en ambas colas, porque la routing key order.created coincide con los dos bindings:
sudo rabbitmqctl list_queues -p app name type messages
name type messages
orders.created quorum 5
orders.all quorum 5
Ejecuta el consumidor:
python3 ~/consumer.py
Esperando mensajes. Pulsa Ctrl+C para salir.
Procesando pedido 1
Procesando pedido 2
Procesando pedido 3
Procesando pedido 4
Procesando pedido 5
Pulsa Ctrl+C y vuelve a listar las colas: orders.created estará a 0 y orders.all seguirá con 5 mensajes, porque nadie la consume. También puedes revisar los bindings creados con sudo rabbitmqctl list_bindings -p app.
Paso 7: Limitar el tamaño de las colas con políticas
Una cola sin consumidores crece hasta agotar memoria o disco. Las políticas aplican límites a varias colas a la vez sin tocar el código. Esta limita las colas que empiezan por orders. a 100.000 mensajes y descarta los más antiguos al superarlo:
sudo rabbitmqctl set_policy -p app orders-limits "^orders\." \
'{"max-length": 100000, "overflow": "drop-head"}' --apply-to queues
Comprueba que se aplica:
sudo rabbitmqctl list_policies -p app
sudo rabbitmqctl list_queues -p app name policy
name policy
orders.created orders-limits
orders.all orders-limits
Si prefieres que los publicadores reciban un rechazo en vez de perder los mensajes más antiguos, usa "overflow": "reject-publish".
Solución de problemas
ACCESS_REFUSED - Login was refused: usuario o contraseña incorrectos, o intentas usarguestdesde otra máquina. Crea un usuario propio como en el paso 4.ACCESS_REFUSED ... access to queue ... refused: el nombre de la cola o del exchange no encaja con los patrones deset_permissions.- Los publicadores se quedan bloqueados: se ha disparado una alarma de memoria o de disco. Compruébalo con
sudo rabbitmq-diagnostics alarmsy libera espacio o ajusta los umbrales del paso 3. - El nodo no arranca tras cambiar el hostname: RabbitMQ guarda los datos bajo el nombre
rabbit@hostname. Mantén el hostname estable en servidores con RabbitMQ.
Conclusión
Tienes RabbitMQ instalado desde el repositorio oficial, con un vhost aislado, usuarios con permisos mínimos, la consola web accesible por túnel SSH y un flujo de productor y consumidor con colas quorum y confirmaciones. Como siguientes pasos, configura TLS para las conexiones AMQP, añade una política de dead-lettering para los mensajes que fallen y, si necesitas alta disponibilidad, forma un clúster de tres nodos para que las colas quorum se repliquen.
