# T.1.3.2 RabbitMQ - Protocolo AMQP ![](https://i.imgur.com/dszF8Ih.png) RabbitMQ es un intermediario de mensajes: acepta y reenvía mensajes. Puede pensar en ello como una oficina de correos: cuando coloca el correo que desea publicar en un buzón, puede estar seguro de que el cartero finalmente entregará el correo a su destinatario. En esta analogía, RabbitMQ es un apartado postal, una oficina postal y un cartero. La principal diferencia entre RabbitMQ y la oficina de correos es que no se ocupa de papel, sino que acepta, almacena y reenvía blobs binarios de datos. A continuación algunas caracteristicas: * En el entorno de RabbitMQ un progama que envía mensajes es un productor: ![](https://i.imgur.com/RVm0Piq.png) * Una cola es el nombre de un buzón que se encuentra dentro de RabbitMQ. Aunque los mensajes fluyen a través de RabbitMQ y sus aplicaciones, solo se pueden almacenar dentro de una cola. Una cola solo está limitada por los límites de memoria y disco del host (servidor), es esencialmente un gran búfer de mensajes. Muchos productores pueden enviar mensajes que van a una cola y muchos consumidores pueden intentar recibir datos de una cola. Así es como representamos una cola: ![](https://i.imgur.com/bncxu84.png) * Consumir tiene un significado similar a recibir. Un consumidor es un programa que principalmente espera recibir mensajes: ![](https://i.imgur.com/YGUUbCq.png) **Nota.- Tenga en cuenta que el productor, el consumidor y el corredor no tienen que residir en el mismo host; de hecho, en la mayoría de las aplicaciones no lo hacen. Una aplicación también puede ser productora y consumidora.** ## Instalación de la librería Pika RabbitMQ habla varios protocolos. Este tutorial utiliza AMQP 0-9-1, que es un protocolo abierto de uso general para mensajería. Hay varios clientes para RabbitMQ en muchos idiomas diferentes. En esta serie de talleres se va a utilizar Pika 1.2.0, que es el cliente de Python recomendado por el equipo de RabbitMQ. Para instalarlo, puede usar la herramienta de administración de paquetes pip que se puede ejecutar desde el entorno de comando de Anaconda Prompt. La sentencia que permite instalar pika pueden variar según el uso que se requiera. A continuación se indica los métodos de instalación: Desde una línea de comando de Anaconda ejecute el comando siguiente y espere que el entorno descargue las librerias necesiarias para su instalación: ```shell conda install -c conda-forge pika ``` Otros métodos se muestra a continuación: ```shell pip install pika --upgrade. ``` En la figura siguiente se observa el resultado de la instalación de Pika. ![](https://i.imgur.com/akkKFnU.png) Para los usuarios que han usado un ambiente "enviroment" diferente a continuación se muestra se indica el comando que se debe usar para instalar la libreria en dicho "environment". ```shell conda activate Master2023 pip install pika --upgrade ``` En la figura siguiente se muestra la respuesta del mismo. ![](https://i.imgur.com/Xl2qS1k.png) Usando el método tradicional dentro de un entorno de comando de Windows. A continuación dicha sentencia: ```shell python -m pip install pika --upgrade ``` ## Creacción de un productor Python usando AMQP Usando la librería Pika se procede a crear un cliente que permita enviar datos (productor) al servidor RabbitMQ. Para este propósito, se recomienda abrir el software Spyder y crear un proyecto nuevo cuyo nombre puede ser AMQP. Una vez, creado dicho dicho proyecto y dentro del mismo crea un nuevo archivo y guarde con el nombre `amqp-productor.py`. Nuestro primer programa `amqp-productor.py` enviará un solo mensaje a la cola del broker Localhost. A continuación se describen dicho programa ```python= import pika, sys mExchange='' mQueue='hello' connection = pika.BlockingConnection( pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue=mQueue) message = ' '.join(sys.argv[1:]) or 'Hello World!' channel.basic_publish(exchange=mExchange, routing_key=mQueue, body=message) print("[x] Message sent to consumer: ", message) connection.close()# -*- coding: utf-8 -*- print("Fin de ejecución") ``` A continuación detalles del código usado. 1. Se importa la librería Pika y sys. Ver línea 1. 2. Se estable dos variables para el uso del intercambiador y la cola. En este caso el intercambiador se tomará por defecto. 3. Se estable la conexión con el servidor RabbitMQ. Ver Línea 5-6. Esto, permite conectarse al broker en la máquina local, de ahí el localhost. Si quisiéramos conectarnos a un broker en una máquina diferente, simplemente cambiamos su nombre o dirección IP. 4. Se debe asegurar de que exista la cola de destinatarios. Si enviamos un mensaje a una ubicación no existente, RabbitMQ simplemente soltará el mensaje. Creamos una cola "hello" de saludo a la que se entregará el mensaje. Linea 9 5. Luego, se procede a enviar el mensaje 'hello world!'. Línea 13. Es notorio que el método basic_publish permite enviar dicha cadena de texto al servidor. Las variables "exchange", and "routing_key" serán descritas en otro ejemplo. 6. Se muestra un mensaje 7. Se cierra conexión. ## Creacción de un consumidor Python usando AMQP Siguiendo con el estilo anterior, ahora, continuaremos con el código que permite recibir los datos del productor. Es decir se se creará el consumidor. Para este propósito usaremos nuevamente la libreria Pika y usando el software Spyder cree un nuevo archivo en el entorno de trabajo o directorio descrito anteriormente. El nombre del archivo se puede llamar `amqp-consumidor.py` . En la siguiente figura se muestra qué, el consumidor obtiene los datos de la cola denominada "hello". **RabbitMQ para desplegar la información tanto el consumidor como el productor debe tener un mismo nombre de cola**. ![](https://i.imgur.com/zRPnSO9.png) ```python= #!/usr/bin/env python import pika, sys, os mQueue='hello' def main(): connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue='hello') def callback(ch, method, properties, body): print(" [x] Received %r" % body) channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming() if __name__ == '__main__': try: main() except KeyboardInterrupt: print('Interrupted') try: sys.exit(0) except SystemExit: os._exit(0) ``` A continuación detalles del código usado. 1. Se importa la librería Pika, "sys" y "os" que son necearias para controlar las interrupciones (errores) y salir de la ejecución. Ver línea 1. 2. Se declara la variable cola la misma que indica a que cola se unirá el consumidor. 3. Desde la línea 4 - 16 se observa un módulo principal. Dicho modulo permite connectarse al broker y habilitar el servicio de escucha para recibir la información del productor (amqp-send1). Dentro de este método se observa un procedimiento denominado "callback" dicho procedimiento permite mostrar los datos mediante la variable "body". Para iniciar lo anterior se declara el método "basic_consume" de la variable "channel" en donde recibe la función "callback". Cabe indicar qué dicha funcionalidad inicia una vez qué se ejecute el método "channel.start_consuming()". >Recibir mensajes de la cola es más complejo. Funciona suscribiendo una función de devolución de llamada a una cola. Siempre que recibimos un mensaje, la biblioteca Pika llama a esta función de devolución de llamada. En nuestro caso esta función imprimirá en pantalla el contenido del mensaje. 4. En la línea 18 al 26 permite la ejecución del programa y controla los errores en caso de excepción. Entre estas líneas se encuentra la llamada al procedimiento principal -> main(). ## Ejecución de los programas desarrollados Para ejecutar los programas `amqp-productor.py` y `amqp-consumidor.py` se los puedes realizar de dos maneras: i) la primera es mediante el uso del entorno Spyder y la ii) mediante la consola de anaconda. Existe una tercera opción que es mediante la consola de windows (DOS). Para el entorno de Spyder necesitamos aperturar una nueva consola. La idea es tener dos consolas. La consola número 1 para visualizar el dato recibido (ejecución del receiver), y la consola número 2 para enviar los datos. En la figura que se muestra a continuación, se resalta el entorno de Spyder con la dos consolas. Se observa que la consola número 1 se encuentra en ejecución y en espera que se reciba un dato del primer programa `amqp-productor.py`. ![](https://i.imgur.com/2etxqTu.png) Otra manera de ejecutar estos programas es mediante unas ventanas de líneas de comandos. Esta opción permite mantener n ventanas de comandos en ejecución al mismo tiempo. Para hacerlo, basta con ir a la barra de tarea de su sistema operativo Windows y ejecutar Anaconda Prompt. Cabe indicar que es necesario abrir dos ventanas de comandos para visualizar el comportamiento de la solución propuesta. A continuación los pasos a seguir: 1. Una vez, que esté dentro de la línea de comando se debe ubicar en el directorio donde se encuentra los programas desarrollados. 2. Ejecutar en primer lugar el programa que hará las funciones de consumidor "amqp-receiver1". Para dicho propósito se debe ejecutar el siguiente comando: ``` python archivo-a-ejecutar.py ``` 3. En la figura se muestra la ejecución de los programas indicados. ![](https://i.imgur.com/DVf2q5m.png) :::info :bulb: **Tarea**: Se le solicita que realice lo siguiente: 1 Modifiqué el programa amqp-productor cambiando el nombre de la cola ejecute y evalué que ocurre con el consumidor. 2 Habrá 2 ventanas de líneas de comando y ejecute el programa amqp-consumidor y luego envíe datos desde del programa amqp-productor. Verifique que ocurre con las ventanas de consumidores. Recuerde que ambos programas debe tener la misma cola. ::: **Referencia bibliográficas:** 1. [RabbitMQ - Hello World](https://www.rabbitmq.com/tutorials/tutorial-one-python.html)