La missatgeria asíncrona és una tècnica de comunicació entre microserveis que permet que els serveis es comuniquin sense necessitat d'esperar una resposta immediata. Aquesta tècnica és especialment útil per a sistemes distribuïts on la latència i la disponibilitat poden variar.
Conceptes Clau
- Asincronia: La comunicació no és immediata; el servei emissor no espera una resposta immediata del servei receptor.
- Cues de Missatges: Utilitzades per emmagatzemar missatges fins que el servei receptor estigui disponible per processar-los.
- Publicació/Subscripció (Pub/Sub): Un patró on els serveis publiquen missatges a un canal i altres serveis es subscriuen per rebre aquests missatges.
- Durabilitat: Garantia que els missatges no es perdran, fins i tot si hi ha fallades en el sistema.
Avantatges de la Missatgeria Asíncrona
- Desacoblament: Els serveis no necessiten conèixer l'estat o la disponibilitat dels altres serveis.
- Escalabilitat: Permet gestionar grans volums de missatges sense sobrecarregar els serveis.
- Resiliència: Els missatges es poden emmagatzemar i processar més tard si un servei està temporalment fora de servei.
Desavantatges de la Missatgeria Asíncrona
- Complexitat: Afegir cues de missatges i gestionar la consistència pot augmentar la complexitat del sistema.
- Latència: Pot haver-hi un retard en el processament dels missatges.
- Gestió d'Errors: És més complicat gestionar errors i garantir la consistència de dades.
Eines i Tecnologies Populars
| Eina/Servei | Descripció |
|---|---|
| RabbitMQ | Sistema de missatgeria que implementa el protocol AMQP. |
| Apache Kafka | Plataforma de streaming distribuït que permet la publicació i subscripció. |
| Amazon SQS | Servei de cua de missatges completament gestionat per AWS. |
| Google Pub/Sub | Servei de missatgeria asíncrona gestionat per Google Cloud. |
Exemples Pràctics
Exemple 1: Enviament de Missatges amb RabbitMQ
import pika
# Connexió a RabbitMQ
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# Creació de la cua
channel.queue_declare(queue='hello')
# Enviament del missatge
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
# Tancament de la connexió
connection.close()Exemple 2: Recepció de Missatges amb RabbitMQ
import pika
# Connexió a RabbitMQ
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# Creació de la cua
channel.queue_declare(queue='hello')
# Definició de la funció de callback
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
# Consumir missatges de la cua
channel.basic_consume(queue='hello',
on_message_callback=callback,
auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()Exercici Pràctic
Objectiu
Implementar un sistema de missatgeria asíncrona utilitzant RabbitMQ per enviar i rebre missatges entre dos microserveis.
Passos
- Instal·lar RabbitMQ: Assegura't de tenir RabbitMQ instal·lat i en funcionament.
- Crear un Productor: Escriu un servei que enviï missatges a una cua.
- Crear un Consumidor: Escriu un servei que rebi i processi missatges de la cua.
Solució
Productor
import pika
def send_message(message):
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='task_queue', durable=True)
channel.basic_publish(exchange='',
routing_key='task_queue',
body=message,
properties=pika.BasicProperties(
delivery_mode=2, # make message persistent
))
print(" [x] Sent %r" % message)
connection.close()
send_message('Hello, Microservices!')Consumidor
import pika
import time
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
time.sleep(body.count(b'.'))
print(" [x] Done")
ch.basic_ack(delivery_tag=method.delivery_tag)
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='task_queue', durable=True)
channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='task_queue', on_message_callback=callback)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()Errors Comuns i Consells
- No Persistir Missatges: Assegura't que els missatges siguin persistents per evitar pèrdues en cas de fallades.
- No Gestionar Errors: Implementa mecanismes per gestionar errors i reintents.
- Sobrecàrrega de la Cua: Monitoritza la cua per evitar sobrecàrregues i assegurar un processament eficient.
Conclusió
La missatgeria asíncrona és una tècnica poderosa per a la comunicació entre microserveis, permetent desacoblament, escalabilitat i resiliència. Tot i que pot afegir complexitat al sistema, els avantatges superen els desavantatges en molts casos. Amb les eines i tecnologies adequades, pots implementar sistemes robustos i eficients.
En el següent tema, explorarem els diferents protocols de comunicació com gRPC i GraphQL, que ofereixen alternatives a les APIs RESTful i la missatgeria asíncrona.
Curs de Microserveis
Mòdul 1: Introducció als Microserveis
- Conceptes Bàsics de Microserveis
- Avantatges i Desavantatges dels Microserveis
- Comparació amb Arquitectura Monolítica
Mòdul 2: Disseny de Microserveis
- Principis de Disseny de Microserveis
- Descomposició d'Aplicacions Monolítiques
- Definició de Bounded Contexts
