Diario
Secciones
Ajustes de lectura
Ninguna voz para este idioma en este navegador.
Más voces
Código y términos técnicos en inglés
Desactivado: la voz de la página lo lee todo, sin pausa entre dos voces.
Ninguna voz para este idioma en este navegador.
Más voces
Más voces: Microsoft Edge ofrece voces naturales en línea, y Windows (Configuración › Hora e idioma › Voz), macOS y Android instalan otras.
Progreso
Sección titulada «Progreso»- Lección 1 — Primeros pasos
- Lección 2 — Topología: exchanges, bindings y colas
- Lección 3 — Clientes en C#, Java y Spring AMQP
- Lección 4 — Fiabilidad: acuses de recibo, prefetch, confirmaciones
- Lección 5 — Tipos de colas: clásicas, quorum y streams
- Lección 6 — Errores: dead lettering, TTL, reintentos y mensajes diferidos
- Lección 7 — Patrones: work queues, publish/subscribe, RPC, consumidores en competencia, outbox
- Lección 8 — Clustering y alta disponibilidad
- Lección 9 — Seguridad: virtual hosts, usuarios, permisos, TLS
- Lección 10 — Observabilidad: Prometheus, Grafana, alarmas, control de flujo
- Lección 11 — Rendimiento y dimensionamiento
- Lección 12 — Otros protocolos: streams, MQTT, AMQP 1.0; RabbitMQ y Kafka
- Lección 13 — Operaciones: actualizaciones, definiciones, Kubernetes
2026-09-15 — Lecciones 1 a 4
Sección titulada «2026-09-15 — Lecciones 1 a 4»- La página de release information indicaba 4.3.5 como última versión a 2026-09-15, y el tag
rabbitmq:4.3.5-managementde Docker Hub se había construido el 2026-09-10. La imagen ejecuta Erlang/OTP 27.3.4.17. Los clientes son los últimos de NuGet y Maven Central ese día: RabbitMQ.Client 7.2.2 y amqp-client 5.35.0. Spring Boot 4.1.1 gestiona amqp-client 5.30.0 y Spring AMQP 4.1.1; el POM padre del curso sube el cliente a 5.35.0 con la propiedadrabbit-amqp-client.version, para que los dos programas Java usen el mismo cliente. - El código es un proyecto C# con un comando por ejemplo (
csharp) y un build de Maven con dos módulos, un JAR shaded para el cliente Java y un JAR de Spring Boot (java).check.shejecuta 36 pasos contra un broker recién creado, incluidos comandosrabbitmqctlyrabbitmq-diagnosticsy un reinicio del broker, y compara cada salida conexpected/. Lo ejecuté dos veces seguidas sobre contenedores nuevos en Windows con los mismos resultados. - CI: los runners de Windows y macOS alojados por GitHub no tienen Docker, así que el workflow compila allí los clientes y lo ejecuta todo contra un contenedor de servicio de RabbitMQ solo en Linux.
- Para obtener una salida determinista de un broker, los programas evitan depender del tiempo: leen las colas con
basic.getdespués de publicar, detienen a los consumidores tras un número conocido de mensajes, y no imprimen ningún consumer tag generado por el servidor. Dos ejemplos aún esperan un poco: 300 ms tras un fallo simulado, para que la ventana de prefetch se llene, y 500 ms para comprobar que un consumidor no recibe un cuarto mensaje. - Ninguno de los repositorios de GuitarAlchemist usa RabbitMQ en su código (ga en
dc2e74cb, ix ened5e998, tars en54487423). La única configuración que encontré es un archivo Docker Compose generado en tars: ejecutarabbitmq:3.12-management, una serie que ya no está en la lista de versiones soportadas, con un volumen de datos pero sinhostname, de modo que un contenedor recreado arrancaría con un nombre de nodo nuevo y no encontraría sus datos, y fija en el código las credencialesadmin/admin123. Su health check,rabbitmq-diagnostics pingcomo root, es el patrón que tumbó mi broker, aunque un intervalo de 30 segundos hace improbable la carrera.
El broker que se detenía antes de arrancar. Mi primer broker.sh esperaba al broker ejecutando docker exec rabbitmq rabbitmq-diagnostics check_port_connectivity cada segundo. El contenedor moría en menos de dos segundos con Error when reading /var/lib/rabbitmq/.erlang.cookie: eacces. La CLI, ejecutada como root, creó la cookie de Erlang antes que el nodo; el nodo, ejecutado como rabbitmq, no podía leerla. Lo reproduje con un solo docker exec justo después de docker run, y ls -la mostraba el archivo como propiedad de root. Ejecutar el contenedor con --user rabbitmq lo arregló, con un health check cada segundo. Es docker-library/rabbitmq#695, cerrada sin comentarios en 2024; la documentación de la imagen no lo menciona. La lección 1 cuenta la historia.
Sorpresas:
- RabbitMQ 4.3.5 rechaza una cola declarada con
durable: falsesalvo que sea exclusiva:541 INTERNAL_ERROR - Feature transient_nonexcl_queues is deprecated, un error de conexión. Todos los tutoriales antiguos que declarandurable: falsefallan con esta versión. - Ese texto de error termina en
To...: los textos de respuesta de AMQP son short strings de 255 bytes como mucho, y el aviso de obsolescencia es más largo. - Un mensaje no enrutable publicado sin
mandatoryse confirma. Una confirmación de publicación dice que el broker ha terminado con el mensaje, no que una cola lo tenga. - Con el seguimiento de confirmaciones, RabbitMQ.Client 7 lanza
PublishReturnExceptionpara un mensaje devuelto; el cliente Java informa la misma publicación como confirmada y llama alReturnListenerjusto antes. redelivereddepende de la ventana de prefetch: sin límite, los mensajes que un consumidor caído nunca miró vuelven conredelivered=True.- El convertidor de Jackson de Spring AMQP escribe el nombre de la clase Java,
dev.learn.rabbitmq.spring.OrdersApplication$Order, en una cabecera__TypeId__, y prescinde de ella cuando el tipo del parámetro del listener es concreto. - Justo después de arrancar un broker,
curl "…/api/queues/%2F/hello?columns=name,messages,consumers"devolvía solo{"name":"hello"}. En otra ejecución, seis segundos después de publicar, la misma petición devolvía{"consumers":0,"messages":2,"name":"hello"}. El plugin de gestión recoge las estadísticas de las colas periódicamente, así que la API HTTP va unos segundos por detrás derabbitmqctl. El intervalo exacto en 4.3.5 está por verificar. - Sin nada escuchando en el puerto 5672 en Windows, el cliente .NET tardó 4,3 segundos en informar
BrokerUnreachableException, el cliente Java 165 milisegundos. Una fracción de segundo después dedocker rm -f, Docker Desktop aún aceptaba la conexión TCP y el cliente .NET informabaconnection.start was never receiveden su lugar.
Lo que hice mal al principio:
- Git Bash convertía
/var/lib/rabbitmq/endocker exec rabbitmq ls /var/lib/rabbitmq/en una ruta de Windows bajoC:/Program Files/Git.MSYS_NO_PATHCONV=1lo impide;check.shlo fija para los comandos que se ejecutan en el contenedor. Fijarlo para todo el script rompía en cambio el script de arranque de Maven. - El POM padre de Spring Boot configura el plugin Maven Shade con sus propios transformers, y Maven fusionaba mi
ManifestResourceTransformercon uno de ellos: «Cannot find ‘resource’ in class ManifestResourceTransformer».combine.self="override"en<transformers>lo arregló. - La primera versión de los volcados de colas imprimía la clave de enrutamiento de cada mensaje antes de su cuerpo. Los mensajes headers y fanout tienen una clave vacía o sin sentido, y la salida tenía espacios dobles; los volcados imprimen ahora los cuerpos, y los ejemplos topic usan la clave de enrutamiento como cuerpo.
- Mi primer push fue rechazado: el token de GitHub ya no tenía el scope
workflow, necesario para crear un archivo en.github/workflows. El código salió primero; el workflow espera al scope, así que hasta entonces la CI no ejecuta estos programas.
Preguntas abiertas
Sección titulada «Preguntas abiertas»- Los comandos de
wslcy Podman de la lección 1, y los de Linux y macOS, están por verificar; la CI ejecuta la imagen en Linux. - La recuperación automática de conexiones en ambos clientes tras un reinicio del broker: por verificar con un programa, probablemente en la lección 8.
- Qué le hace a la entrega una excepción lanzada desde un handler
ReceivedAsyncde RabbitMQ.Client 7, y el error de conversión de un listener de Spring con un parámetro de tipo interfaz y sin__TypeId__: por verificar en la lección 6. deprecated_features.permit.transient_nonexcl_queues = truepara volver a permitir colas no durables en 4.3.5: por verificar.- Adónde van los 4,3 segundos de la conexión rechazada del cliente .NET en Windows: por verificar.
- El rendimiento de los mensajes persistentes frente a los transitorios, y de las confirmaciones por mensaje frente a las confirmaciones por lotes: por verificar en la lección 11.