This is an old revision of the document!
În cadrul acestui laborator, veți parcurge mai întâi un breviar teoretic pentru a înțelege cum funcționează RabbitMQ, care sunt principalele concepte ale acestei tehnologii, cum să rulați o instanță de RabbitMQ local și cum să o utilizați cu Python. În această primă parte nu este necesar să rulați nimic; materialul oferit are rol de suport pentru partea a doua.
Partea a doua constă într-o serie de exerciții care vor aplica tot ceea ce s-a explicat în breviarul teoretic și vă vor ajuta să aprofundați cunoștințele prin exemple practice.
RabbitMQ este un broker de mesaje open-source bazat pe protocolul AMQP (Advanced Message Queuing Protocol) utilizat pentru a permite aplicațiilor să comunice eficient și asincron prin trimiterea de mesaje între ele. Acesta este folosit pentru a decupla componentele aplicațiilor, facilitând astfel comunicarea, scalabilitatea și reziliența în arhitecturi distribuite și microservicii.
MQTT (Message Queuing Telemetry Transport) este un protocol de comunicație optimizat pentru dispozitive IoT (Internet of Things), senzori, rețele cu lățime de bandă redusă și comunicații instabile. MQTT a fost proiectat pentru latență mică și consum minim de energie.
Spre deosebire de RabbitMQ care folosește AMQP, MQTT utilizează un model publish/subscribe, bazat pe un server central numit broker.
Aplicații tipice MQTT:
| Caracteristică | RabbitMQ / AMQP | MQTT |
|---|---|---|
| Domeniul principal | Sisteme enterprise, microservicii | IoT, dispozitive embedded |
| Complexitate | Ridicată | Redusă |
| Transport | TCP | TCP / WebSockets |
| Schemă mesaje | Structurată, headere multe | Minimul posibil (~2 bytes) |
| Persistență | Da | Opțional (QoS) |
routing key exact.routing key.routing key, permițând un nivel ridicat de flexibilitate. https://www.rabbitmq.com/tutorials/tutorial-five-python
Pentru a conecta o aplicație Python la RabbitMQ, vei folosi biblioteca pika, care este un client AMQP popular pentru Python. Aceasta permite crearea conexiunilor, configurarea exchange-urilor și queue-urilor, și trimiterea sau recepționarea mesajelor prin RabbitMQ.
Arhitectură de tip Publish / Subscribe
QoS (Quality of Service)
| Nivel QoS | Garanție livrare | Explicație |
| 0 | At most once | Fără garanție (ca UDP) |
| 1 | At least once | Posibile duplicate |
| 2 | Exactly once | Cel mai sigur, dar mai lent |
Exemplu de topic ierarhic:
casa/living/temperatura
Wildcard-uri în topic:
+ – un singur nivel# – toate nivelurile următoarecasa/+/temperatura -> casa/living/temperatura casa/# -> toate subtopic-urile
Pentru a putea folosi o instanță de RabbitMQ, aveți două posibilități: să o instalați pe calculatorul personal (Installing RabbitMQ | RabbitMQ) sau să rulați următoarea comandă Docker Compose: docker compose up folosind următorul fișier docker-compose.yaml:
version: '3.8' services: rabbitmq: image: rabbitmq:3-management container_name: rabbitmq environment: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest ports: - "5672:5672" # Port for AMQP protocol - "15672:15672" # Port for RabbitMQ management UI volumes: - rabbitmq_data:/var/lib/rabbitmq networks: - rabbitmq_network volumes: rabbitmq_data: networks: rabbitmq_network: driver: bridge
Comandă rulare pentru docker-compose.yaml prezentat anterior:
docker-compose up -d
RabbitMQ oferă și o interfață grafică de management (Management UI) pentru o monitorizare și administrare mai ușoară a mesajelor, queue-urilor și exchange-urilor, fiind accesibilă în mod implicit pe portul 15672 (http://localhost:15672). User-ul și parola implicite sunt guest/guest, însă aceste credențiale funcționează doar pentru accesul de pe localhost; pentru accesul extern este necesară configurarea unor utilizatori noi.
Pentru a conecta o aplicație Python la RabbitMQ, vei folosi biblioteca pika, un client AMQP popular pentru Python. Aceasta permite crearea conexiunilor, configurarea exchange-urilor și queue-urilor, și trimiterea sau recepționarea mesajelor prin RabbitMQ.
Pași pentru conectarea la RabbitMQ folosind Python
1. Instalarea bibliotecii pika
Asigură-te că ai instalat biblioteca pika. Poți face acest lucru rulând următoarea comandă:
pip install pika
2. Configurarea unei Conexiuni la RabbitMQ
Pentru a te conecta la RabbitMQ, va trebui să definești parametrii de conectare. În mod implicit, RabbitMQ rulează local pe portul 5672, iar contul implicit este guest cu parola guest.
import pika # Configurarea conexiunii la RabbitMQ credentials = pika.PlainCredentials("guest", "guest") connection_params = pika.ConnectionParameters(host='localhost', port=5672, credentials=credentials) connection = pika.BlockingConnection(connection_params) channel = connection.channel() print("Conexiunea la RabbitMQ a fost stabilită.")
Acest cod:
localhost.channel, care este un canal de comunicare utilizat pentru a interacționa cu RabbitMQ.Notă: Dacă RabbitMQ rulează pe un alt server sau port, schimbălocalhostcu adresa IP și/sau specifică portul prinConnectionParameters.
3. Crearea unui Queue
Pentru a trimite și primi mesaje, ai nevoie de un queue (coadă) în care să fie stocate mesajele. Poți crea un queue folosind queue_declare:
queue_name = 'my_queue' channel.queue_declare(queue=queue_name) print(f"Queue-ul '{queue_name}' a fost creat.")
Acest cod va crea un queue numit my_queue (sau se va conecta la el dacă deja există). Queue-ul este o structură FIFO (First In, First Out) care stochează mesajele până când sunt preluate de consumatori.
4. Trimiterea unui Mesaj în Queue
Pentru a trimite un mesaj, vei folosi metoda basic_publish:
message = "Salut din RabbitMQ!" channel.basic_publish(exchange="", routing_key=queue_name, body=message) print(f"Mesaj trimis: {message}")
exchange=”” specifică că mesajul este trimis direct către queue-ul specificat de routing_key.routing_key=queue_name indică queue-ul în care trebuie să ajungă mesajul.body=message este conținutul mesajului trimis.5. Primirea unui Mesaj din Queue
Pentru a primi mesaje, definești un consumator. Acesta va utiliza un callback pentru a procesa fiecare mesaj primit:
def callback(ch, method, properties, body): print(f"Mesaj primit: {body.decode()}") channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True) print("Aștept mesaje...") channel.start_consuming()
callback este o funcție care primește și afișează mesajele.basic_consume configurează consumatorul să asculte queue-ul specificat (queue_name) și să apeleze callback pentru fiecare mesaj care este primit (“să consume mesjul”).auto_ack=True confirmă automat mesajele ca fiind procesate imediat ce sunt primite. După ce sunt procesate, acestea vor fi șterse de pe queue.6. Închiderea Conexiunii
După ce ai terminat de trimis și primit mesaje, închide conexiunea la RabbitMQ pentru a elibera resursele:
connection.close() print("Conexiunea la RabbitMQ a fost închisă.")
Pentru a vedea un exemplu complet despre cum două aplicații, un sender și un receiver, comunică folosind RabbitMQ, precum și pentru a citi explicații mai detaliate, vizitați acest tutorial: Hello World.
În cadrul acestuia veți găsi exemplificat întregul proces de conectare la RabbitMQ: crearea unei cozi (queue), trimiterea și recepția mesajelor, precum și închiderea conexiunii.
Utilizare
Exchange-urile fanout sunt utile pentru aplicații de tip difuzare (broadcast), unde același mesaj trebuie să fie recepționat de toate queue-urile conectate. Acest tip de exchange este ideal pentru scenarii precum notificările de sistem, unde toate instanțele trebuie să fie informate simultan.
Pentru a conecta o aplicație Python la MQTT, vei folosi biblioteca paho-mqtt. Aceasta permite crearea și configurarea conexiunilor, și trimiterea sau recepționarea mesajelor prin MQTT.
Asigură-te că ai instalat biblioteca paho-mqtt. Poți face acest lucru rulând următoarea comandă:
pip install paho-mqtt
Următoarea secvență de cod implementează un nod de tip publisher care trimite mesaje prin MQTT:
import paho.mqtt.client as mqtt BROKER = "localhost" PORT = 1883 USERNAME = "user" PASSWORD = "pass" TOPIC = "chat/general" client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) client.username_pw_set(USERNAME, PASSWORD) client.connect(BROKER, PORT) while True: message = input("Message: ") client.publish("chat/general", message) if message == "exit": break client.disconnect()
Următoarea secvență de cod implementează un nod de tip subscriber care primește mesaje venite prin MQTT:
import paho.mqtt.client as mqtt BROKER = "localhost" PORT = 1883 USERNAME = "user" PASSWORD = "pass" TOPIC = "chat/general" def on_message(client, userdata, msg): print(f"Mesaj primit pe topicul {msg.topic}: {msg.payload.decode()}") client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) client.username_pw_set(USERNAME, PASSWORD) client.connect(BROKER, PORT) client.subscribe("chat/general") client.on_message = on_message print("Ascult mesaje MQTT...") client.loop_forever()
Putem vizualiza datele la nivelul broker-ului de mesaje folosind un GUI precum MQTTBox (windows: from Microsoft Store, web: from GitHub)
pip install -r requirements.txt folosind fișierul requirements.txt cu următorul conținut:
Flask==3.1.0 Flask_SocketIO==5.4.1 pika==1.3.2
Rulați local o instanță de RabbitMQ, fie folosind docker-compose-ul pus la dispoziție mai sus, fie instalând RabbitMQ direct pe mașina voastră. Atenție, dacă optați pentru instalarea directă pe mașina voastră, va fi necesar să instalați separat plugin-ul care oferă acces la interfața web - Plugin.
Creează un script Python care să permită citirea textelor de la tastatură și publicarea acestora într-un exchange nou. (care este creat programatic după realizarea cu succes a conexiunii la RabbitMQ). Scriptul va citi textul de la utilizator și va publica fiecare mesaj în exchange-ul RabbitMQ (in mod fanout).
try: while True: message = input("Message: ") channel.basic_publish(exchange=exchange_name, routing_key='', body=message) finally: connection.close()
Creează un script Python care să creeze un queue, să-l lege la exchange-ul din exercițiul 1 și să afișeze fiecare mesaj primit. Scriptul va crea un queue nou și îl va asocia (binding) cu exchange-ul creat în exercițiul anterior. Pentru fiecare mesaj primit în queue, scriptul va afișa conținutul acestuia în consolă.
channel.queue_bind(exchange=exchange_name, queue=queue_name)
Creează un script care citește mesaje de la tastatură și le publică pe un topic MQTT.
Date de conectare la broker-ul MQTT în cloud:
BROKER = "isilab.cloud.shiftr.io" PORT = 1883 USERNAME = "isilab" PASSWORD = "oonhdB7qBZrPK2Lf" TOPIC = "chat/general"
Creează un script care ascultă topic-ul și afișează mesajele primite.
Rulați două terminale:
Test: