# Advanced Message Queuing Protocol

El estándar AMQP (Advanced Message Queuing Protocol) es un protocolo de estándar abierto en la capa de aplicaciones de un sistema de comunicación. Las características que definen al protocolo AMQP son la orientación a mensajes, encolamiento ("queuing"), enrutamiento (tanto punto-a-punto como publicación-subscripción), exactitud y seguridad.
AMQP estipula el comportamiento tanto del servidor que provee los mensajes como del cliente de la mensajería hasta el punto de que las implementaciones de diferentes proveedores son verdaderamente interoperables, de la misma manera que los protocolos SMTP, HTTP, FTP y análogos han creado sistemas interoperables. Otros intentos previos de estandarizar middleware sucedieron al nivel de API (por ejemplo, JMS) y no lograron una interoperabilidad real. A diferencia de JMS, que solamente define una API, AMQP es un protocolo a nivel de cable. Un protocolo a nivel de cable (wire level protocol) es una descripción del formato de los datos que son enviados a través de la red como un flujo de octetos. En consecuencia, cualquier programa que pueda crear e interpretar mensajes conforme a este formato de datos puede interoperar con cualquier otra herramienta que cumpla con este protocolo, independientemente del lenguaje de implementación.

## Desarrollo

AMQP fue definido desde mediados de 2004 hasta mediados de 2006 por el banco de inversiones estadounidense JP Morgan Chase e iMatix Corporation, quienes también desarrollaron implementaciones en C/C++ y Java. JP Morgan Chase e iMatix documentaron el protocolo como una especificación interoperable y lo entregaron a un grupo de trabajo que incluía a Red Hat, Cisco Systems, TWIST, IONA e iMatix. A fecha de noviembre de 2009, este grupo de trabajo consta de las siguientes empresas: Bank of America, Barclays, Cisco Systems, Credit Suisse, Deutsche Börse Systems, Envoy Technologies, Inc., Goldman Sachs, Progress Software, iMatix Corporation, JPMorgan Chase Bank Inc. N.A, Microsoft Corporation, Novell, Rabbit Technologies Ltd., Red Hat, Inc., Solace Systems, Tervela Inc., TWIST Process Innovations ltd, WS02 y 29West Inc.
Un objetivo importante del diseño de AMQP era conseguir la creación de pilas de protocolo de estándar abierto para la mensajería de empresa, tanto dentro de la misma organización como entre organizaciones, mediante la combinación de AMQP con alguno de los muchos estándares abiertos que describen transacciones de negocio, como FpML o más genéricamente protocolos de transporte seguro de SOAP.
Aunque AMQP tiene sus orígenes en la industria financiera, es aplicable a una amplia gama de problemas de middleware.

## El modelo AMQP

AMQP define una serie de entidades. Desde la perspectiva de la interconexión las más relevantes son:
* El corredor de mensajes: un servidor al que los clientes AMQP se conectan usando el protocolo AMQP. Los corredores de mensajes pueden ejecutarse en un entorno distribuido, pero esta capacidad es específica de la implementación y no está cubierta por la especificación.
* Usuario: un usuario es una entidad que, mediante la presentación de credenciales tales como una contraseña, puede ser autorizado (o puede no serlo) a conectarse a un corredor.
* Conexión: una conexión física usando por ejemplo TCP/IP o SCTP. Una conexión está ligada a un usuario.
* Canal: una conexión lógica que está unida a una conexión. Así pues, la comunicación a través de un canal posee un estado. Aquellos clientes que realicen operaciones concurrentes mediante una misma conexión deben mantener un canal distinto para cada una de ellas. Aquellos clientes que usen un modelo basado en hilos para la concurrencia pueden, por ejemplo, encapsular la declaración del canal en una variable local de cada hilo.
Las entidades utilizadas para el envío y recepción de mensajes en concreto son todas declaradas dentro de un canal. Una declaración garantiza al cliente que la realiza que la entidad existe (o fue previamente declarada por otro cliente). Cualquier intento de declarar una entidad nombrada con propiedades diferentes de las que poseía cuando fue declarada resulta en un error. Para poder cambiar las propiedades de una entidad nombrada, debe ser primero borrada con anterioridad a su nueva creación.
Algunas de estas entidades están nombradas. Su denominación debe ser única dentro del alcance de la entidad y de su corredor. Dado que los clientes habitualmente no tienen los medios para obtener una lista de todas las entidades nombradas disponibles (al menos no hay una operación tal definida dentro de la especificación AMQP), es el conocimiento del nombre de una entidad lo que permite al cliente realizar operaciones sobre ésta.
Los nombres usan la codificación UTF-8, deben tener una longitud de entre 1 y 255 caracteres y deben empezar por un dígito, una letra o un guion bajo.

### Intercambiadores

Los intercambiadores son las entidades a las que se envía los mensajes. Tienen un nombre así como un tipo y unas propiedades tales como:
* pasivo: el intercambiador no será declarado pero ocurrirá un error si no existe.
* perdurable: el intercambiador sobrevivirá a un reinicio del intercambiador.
* autoborrado: el intercambiador será borrado tan pronto como ya no queden colas vinculadas a él. Aquellos intercambiadores que nunca hayan tenido colas vinculadas nunca serán autoborrados.
Nótese que está prevista la supresión de los intercambiadores en AMQP/1.0.

### Colas

Las colas son las entidades que reciben mensajes. Tienen un nombre y propiedades pero no tienen tipo. Los clientes pueden subscribirse a las colas, con el efecto de que el corredor de mensajes les entregará (mediante un mecanismo de push, es decir, de forma activa por parte del corredor) a los clientes los contenidos de la cola. Alternativamente los clientes pueden hacer saltar activamente mensajes de la cola como crean conveniente (mecanismo de pull).
La cola garantiza que los mensajes son entregados en el mismo orden en que llegaron a la cola; esta ordenación se conoce habitualmente como FIFO. En algunos casos de reenrutamiento (por ejemplo debido a un fallo que implique un reinicio del corredor) este orden no se garantiza.
Las propiedades de las colas incluyen:
* intercambiador alternativo: cuando un mensaje es rechazado por un subscriptor o queda huérfano debido a la destrucción de una cola, son reenrutados a un intercambiador alternativo y borrados de esta cola.
* pasiva: la cola no será declarado pero ocurrirá un error si no existe.
* perdurable: la cola sobrevivirá a un reinicio del corredor.
* exclusiva: solo puede haber un cliente para esta cola específica.
* autoborrado: la cola será borrada tan pronto como no queden suscripciones activas para ella. Esta propiedad comparte la misma limitación que la propiedad de autoborrado para los intercambiadores: si ninguna suscripción ha estado jamás activa para esta cola, no será autoborrada. Una cola exclusiva, sin embargo, siempre será autoborrada cuando el cliente cierre la sesión.
Nótese que está previsto que las colas reemplacen a los intercambiadores en AMQP/1.0.

### Mensajes

Los mensajes no tienen nombre y son publicados en un intercambiador. Consisten en un encabezamiento y un cuerpo de contenido. Mientras que el cuerpo contiene datos opacos, el encabezamiento contiene una serie de propiedades opcionales:
* clave de enrutamiento (routing-key): este campo se usa de diferentes formas dependiendo del tipo de intercambiador.
* inmediato: el mensaje será tratado como imposible de enrutar si al menos una de las colas que deberían recibir el mensaje no tiene ninguna suscripción.
* modo de entrega: indica que un mensaje puede necesitar perdurabilidad. Solo para este tipo de mensajes puede el corredor hacer un intento (best-effort) para impedir la pérdida del mensaje antes de que sea consumido. Si hay alguna incertidumbre del lado del corredor sobre la recepción correcta del mensaje (por ejemplo en caso de errores), puede opcionalmente entregar un mismo mensaje más de una vez. Los modos de entrega no persistentes no muestran este tipo de comportamiento.
* prioridad: un indicador (en el rango entre 0 y 9) de que un mensaje tiene precedencia sobre otros.
* vencimiento (expiration): la duración en milisegundos antes de que el corredor pueda tratar el mensaje como imposible de enrutar.

### Vinculaciones

Una vinculación (binding) es una relación entre una cola y un intercambiador que especifica cómo fluyen los mensajes desde el intercambiador a la cola. Las propiedades de la vinculación concuerdan con el algoritmo de enrutamiento que se usa en los intercambiadores. Las vinculaciones (y los algoritmos de los intercambiadores) pueden ser ordenados en una escala de menor a mayor complejidad:
* Incondicional: la vinculación no tiene propiedades y reclama todos los mensajes del intercambiador.
* Condicional con una cadena fija: la vinculación tiene una propiedad, la clave de enrutamiento y reclama todos los mensajes que tengan una clave de enrutamiento idéntica.
* Condicional con un patrón de reconocimiento: la vinculación tiene una propiedad, la clave de enrutamiento y reclama todos los mensajes que sean detectados por un algoritmo de reconocimiento de patrones. Se puede usar cualquier sintaxis arbitraria de patrones. AMQP implementa el reconocimiento de temas.
* Condicional con múltiples cadenas fijas: la vinculación tiene una tabla de propiedades, los argumentos, y reclama todos los mensajes cuyos encabezamientos se correspondan con estos argumentos, usando operaciones lógicas AND o OR para combinar las diferentes correspondencias.
* Condicional con una comparación algorítmica: la vinculación tiene una expresión algorítmica (como una cláusula WHERE en una sentencia SELECT en SQL) y reclama todos los mensajes cuyos encabezamientos se correspondan con esta expresión.
* Condicional con inspección del contenido: la vinculación especifica criterios arbitrarios que solo pueden ser resueltos mediante la inspección del contenido concreto del mensaje.
No todas estas vinculaciones son implementadas de manera estándar, o por todas las implementaciones.

### Tipos de intercambiadores y el efecto de las vinculaciones

Estas cuatro entidades forman el modelo básico de AMQP. La clave para entender cómo un mensaje es pasado a una cola reside en la relación entre el tipo de intercambiador y la interpretación resultante de la clave de enrutamiento.
Un intercambiador entregará como máximo una copia de un mensaje dado a una cola si la clave de enrutamiento en el mensaje se corresponde a una vinculación (otras vinculaciones posteriores semánticamente idénticas no pueden resultar en copias duplicadas del mismo mensaje). Lo que constituye una correspondencia, en cambio, es exclusivamente dependiente del tipo de intercambiador:
* un intercambiador directo considera que hay correspondencia cuando la clave de enrutamiento y la clave de la vinculación son idénticas.
* un intercambiador de abanico (fanout) siempre considera que hay correspondencia, incluso con vinculaciones sin clave.
* un intercambiador con un tema definido (topic exchange) considera que hay correspondencia si la propiedad de clave de enrutamiento de un mensaje coincide con las palabras claves de una vinculación. Estas palabras son cadenas de caracteres separadas por puntos. Dos caracteres adicionales son también válidos: el asterisco "*", que crea una correspondencia con 1 palabra, y la almohadilla "#", que crea una correspondencia con 0 a N palabras. Por ejemplo, *.stock.# tendrá una correspondencia con las claves usd.stock y eur.stock.db, pero no con stock.nasdaq.
* un intercambiador de encabezamientos considera que hay correspondencia en presencia tanto de claves como de pares clave-valor que pueden ser concatenadas con conexiones lógicas AND y OR en el encabezamiento de un mensaje. En este caso, la clave enrutamiento no es un criterio de correspondencia que sea considerado por el intercambiador. Ni tampoco contiene la vinculación una única clave de enrutamiento, sino un formato especial que contiene claves de encabezamiento y/o pares clave-valor que crean una correspondencia al estar presente la clave del encabezamiento o al estar presente la clave del encabezamiento y el valor ser el mismo, respectivamente.
Otros tipos de intercambiadores, por ejemplo específicos del suministrador, son permitidos explícitamente por la especificación.
El concepto de vincular colas denominadas con intercambiadores denominados tiene propiedades poderosas (mientras que la vinculación mantiene ambas entidades independientes entre sí). Es posible, por ejemplo, vincular una única cola mediante vinculaciones múltiples a un único intercambiador, o a varios. O múltiples consumidores pueden compartir el nombre de una cola y vincularse a ella con los mismos parámetros, obteniendo por tanto solo los mensajes que los otros consumidores no hayan consumido. O múltiples consumidores pueden declarar colas independientes pero compartir las mismas vinculaciones y obtener por tanto todos ellos el mensaje que otro consumidor hubiera obtenido en el intercambiador vinculado con estas vinculaciones.

## Revisiones de la especificación y el futuro de AMQP

Las siguientes especificaciones del protocolo AMQP han sido publicadas, en orden cronológico:
* 0-8 en junio de 2006
* 0-9 en diciembre de 2006
* 0-10 (los documentos no tienen una fecha)
* 0-9-1 en noviembre de 2008
* 1.0 borrador en mayo de 2010
* 1.0 final en octubre de 2011
El esbozo 1.0 de la especificación cambia el modelo de AMQP ilustrado más arriba eliminando los conceptos de intercambiadores y de vinculaciones, y reemplazándolos con colas y enlaces (links). Este cambio apunta a remediar dos problemas con el enfoque previo:
* El publicador necesita saber demasiado acerca de la topología del receptor (cuáles intercambiadores y tipos de intercambiadores están disponibles).
* El control de flujo del productor es complejo: si un intercambiador enruta un mensaje a dos colas diferentes, una vacía y la otra casi llena, ¿qué información de control de flujo debe ser mandada al productor y cómo debe ser determinada?
Otros cambios incluye la introducción de un esquema de interpelación directa de colas similar al correo electrónico o a XMPP. Éste eleva interpelaciones a clases de primer orden, y permite la publicación de archivos de localización de servicio (service location records) usando DNS.

## Implementaciones

Éstas son las implementaciones de AMQP que están disponibles públicamente.

### Corredor y cliente

* OpenAMQP, la implementación original en código abierto de AMQP, escrita en C por iMatix. Funciona bajo Linux, AIX, Solaris, Windows y OpenVMS. Incluye un corredor, APIs para C/C++ y Java JMS, una consola de administración remota, secuencias de órdenes, federación, conmutación por error y AMQP-sobre-HTTP mediante el protocolo RestMS.
* AMQP Infrastructure, un paquete instalable mediante yum que cumple con AMQP 0-10 y mantenido para las últimas versiones de Fedora. Incluye el corredor, herramientas de administración, agentes y clientes.
* Apache Qpid, un proyecto de la Apache Software Foundation. Vinculaciones para muchos lenguajes evitando el uso de librerías dinámicas.
* Red Hat Enterprise MRG implementa la versión 0-10 de AMQP cuya gama de características incluye federación, distribución en modo activo-activo usando Qpid como upstream, una consola web y otras características orientadas a empresas.

### Solo corredor

* RabbitMQ, una implementación independiente de código abierto. El servidor está escrito en Erlang y también incluye un cliente de referencia escrito en Java.
* ZeroMQ, una plataforma de mensajería que es capaz de tratar a los corredores de AMQP como nodos de una red de mensajería distribuida. Tiene vinculaciones a su implementación subyacente en C, así como a otros lenguajes como Python, C++, Lisp, Ruby y otros.
* Zyre, un corredor que implementa RestMS y AMQP para permitir acceso HTTP basado en REST a redes AMQP.

### Solo cliente

* DE.SETF.AMQP, una librería cliente de AMQP para Common Lisp.
* amqplib, una librería cliente de AMQP 0-8 para Python, probada con RabbitMQ.