Mensajería punto a punto con Amazon SQS

0 acciones
0
0
0
0

Introducción

El patrón de mensajería punto a punto es un modelo de comunicación común en las arquitecturas web y de nube modernas. Está diseñado para permitir interacciones asincrónicas entre diferentes componentes, como funciones sin servidor o microservicios, lo que les permite intercambiar mensajes sin requerir una respuesta inmediata.

En este patrón, el componente que envía el mensaje se denomina productor, mientras que el componente que lo recibe y lo procesa se denomina consumidor. El productor y el consumidor pueden estar ubicados en el mismo sistema o en sistemas diferentes, lo que lo convierte en un enfoque de comunicación flexible y escalable.

De forma similar a cómo se entregan los correos electrónicos a los destinatarios, los mensajes se envían desde un productor a un consumidor específico. Esto permite una comunicación eficiente y fiable incluso en sistemas distribuidos complejos. Se suele utilizar en situaciones en las que el productor sabe exactamente qué consumidor debe recibir el mensaje, pero no necesita recibir una respuesta inmediata.

El patrón de mensajería punto a punto facilita eficazmente la comunicación y la coordinación entre componentes, mejorando el rendimiento general, la confiabilidad y la escalabilidad de las arquitecturas web y de nube modernas.

Lo que construiremos

En este tutorial paso a paso, implementaremos este patrón utilizando dos funciones de AWS Lambda y una cola de Amazon SQS.

En este tutorial paso a paso, implementaremos un ejemplo simple utilizando dos funciones de AWS Lambda y una cola de Amazon SQS.

Construirás la muestra utilizando TypeScript y AWS Cloud Development Kit (AWS CDK).

El ejemplo constará de tres componentes:
  • Un productor que puede enviar mensajes al consumidor.
  • Un consumidor que puede recibir mensajes del productor.
  • Una cola de mensajes que crea un canal de comunicación entre el productor y el consumidor.


Además de implementar este patrón, también destacaremos la capacidad del AWS Cloud Development Kit (CDK) para definir toda la infraestructura como código. Si desea obtener más información sobre el AWS CDK, consulte la Guía para desarrolladores del AWS CDK.

Al finalizar este tutorial, comprenderá a fondo los componentes individuales de la mensajería punto a punto basada en colas, habrá implementado correctamente comunicaciones asíncronas entre dos funciones Lambda mediante SQS y habrá adquirido experiencia práctica en la creación de infraestructura. Codifique con CDK.

Pero antes de comenzar a codificar, echemos un vistazo rápido a las ventajas y desventajas del patrón de mensajería punto a punto asincrónica.

Ventajas y desventajas del paradigma de mensajería asincrónica punto a punto

Beneficios
  • Acoplamiento flexible: El patrón de mensajería punto a punto asíncrono promueve un acoplamiento flexible entre aplicaciones, lo que les permite comunicarse de forma independiente sin necesidad de una integración estricta. Esta flexibilidad facilita el escalado y la modificación de componentes individuales sin afectar a todo el sistema.
  • Escalabilidad: Este patrón permite un escalamiento horizontal eficiente, ya que se pueden agregar múltiples aplicaciones de consumo para gestionar cargas de trabajo de forma asíncrona. Esto permite que el sistema gestione grandes volúmenes de mensajes y solicitudes simultáneas con mayor eficacia.
  • Confiabilidad: en la mensajería asincrónica, si un mensaje no se entrega o no se procesa, se puede volver a intentar o enviar a una cola de errores para su posterior procesamiento, lo que aumenta la confiabilidad del sistema.
  • Tolerancia a fallos: La mensajería asíncrona proporciona tolerancia a fallos al separar a los productores y consumidores de mensajes. Si una aplicación o componente falla, los mensajes se pueden almacenar para su posterior procesamiento una vez que el sistema se restablezca, garantizando así que no se pierdan datos.
Desventajas
  • Complejidad: La implementación del patrón de mensajería punto a punto asincrónica puede ser más compleja en comparación con otros patrones de integración y requiere una lógica de manejo de mensajes adicional.
  • Dependencias de mensajes y posible duplicación: Gestionar las dependencias entre mensajes y garantizar su correcta eliminación puede ser un desafío en un sistema de mensajería asíncrona. Requiere un diseño e implementación cuidadosos para gestionar posibles problemas como el ordenamiento, la duplicación y las dependencias en el procesamiento de los mensajes.
  • Mayor latencia: La mensajería asincrónica introduce un retraso entre el envío de un mensaje y la recepción de una respuesta, ya que los mensajes pueden tardar más en procesarse. Esta latencia puede afectar las interacciones en tiempo real y puede no ser adecuada para aplicaciones que requieren retroalimentación inmediata.

Al tomar decisiones arquitectónicas, siempre es importante considerar estas ventajas y desventajas y elegir el patrón de comunicación que mejor se adapte a sus requisitos y limitaciones específicos. Muchas aplicaciones modernas se basan en múltiples patrones de integración, incluyendo la mensajería punto a punto asíncrona, la comunicación síncrona de solicitud-respuesta y la comunicación basada en eventos.

Pero ahora, comencemos el tutorial y aprendamos cómo implementar este patrón usando AWS Lambda y Amazon SQS.

Una nota sobre los costos de recursos al codificar: este tutorial utiliza solo la cantidad mínima de recursos, todos los cuales están incluidos en el nivel gratuito que ofrece AWS durante los primeros 12 meses después de la creación de cada cuenta:

  • Unos pocos kilobytes de código se almacenarán en Amazon S3, que proporciona 5 GB de almacenamiento gratuito.
  • Llamamos varias veces a SQS, que ofrece 1 millón de solicitudes gratuitas al mes.
  • Llamaremos a dos funciones en AWS Lambda, que también ofrece 1 millón de invocaciones gratuitas por mes.

Así que, si sigues la guía paso a paso, sin duda te quedarás en el nivel gratuito. También he añadido una sección al final que te ayudará a eliminar todos los recursos creados durante este tutorial.

Requisitos previos

Si tiene la CLI y el CDK instalados, debería ver las versiones de sus instalaciones. De lo contrario, recibirá un error que indica que no se puede encontrar el comando.

Antes de comenzar este tutorial, necesitarás lo siguiente:

  • cuenta de AWS
  • Kit de desarrollo de nube de AWS (AWS CDK)

Este tutorial requiere al menos la versión 2 de AWS CLI y AWS CDK.

Puede determinar la versión de AWS CLI ejecutando el siguiente comando en la terminal:

aws --version

Y la versión de AWS CDK ejecutando el siguiente comando:

cdk --version

Paso 1: Crear la aplicación CDK

1.1 – Iniciar el programa CDK

Primero, debes ocuparte de la configuración inicial y dejar que el CDK genere automáticamente el código que compilará el proyecto.

Desde la línea de comandos, cree un directorio para el proyecto, ingrese al directorio e inicialice el proyecto:

mkdir point-to-point-example
cd point-to-point-example
cdk init app --language typescript

Esto crea la estructura de archivos principal para el proyecto e instala los paquetes necesarios.

Ahora es un buen momento para abrir el proyecto en su IDE favorito y echar un vistazo al proyecto generado y específicamente a los siguientes dos archivos:

point-to-point-example/
├── bin/
│ └── point-to-point-example.ts
├── lib/
│ └── point-to-point-example-stack.ts
└── ...

Archivo bin\ejemplo-punto-a-punto.ts El punto de entrada del programa CDK. No será necesario volver a revisar este archivo en este tutorial.

Archivo lib\pila-de-ejemplo-punto-a-punto.ts Aquí se define la pila principal del programa. En este archivo pasamos la mayor parte del tiempo.

A medida que avanzamos en este tutorial, presentaremos la infraestructura de nuestra aplicación a la clase. Pila de ejemplos de punto a punto En este archivo lo agregaremos. Ábrelo en tu editor y échale un vistazo:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class PointToPointExampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// ...
}
}
1.2 – Arrancar el entorno

La primera vez que implemente una aplicación de AWS CDK en un entorno (es decir, una cuenta y región de AWS específicas), deberá iniciar el entorno con una pila de CDKToolkit. Esta pila implementa un bucket de S3 que se utiliza para almacenar plantillas y recursos durante el proceso de implementación de la aplicación.

Para iniciar el entorno, asegúrese de que todavía está en el directorio punto a punto de ejemplo y ejecute el siguiente comando:

cdk bootstrap

Esto tomará un tiempo y se completará cuando vea el siguiente resultado en su línea de comando:

✅ Environment aws://[account_id]/[region] bootstrapped.
1.3 – Implementar la pila inicial

Para implementar la pila, asegúrese de que todavía está en el directorio punto a punto de ejemplo y ejecute el siguiente comando:

cdk deploy

Este comando compila la aplicación en una plantilla de AWS CloudFormation y la implementa en su cuenta de AWS.


Ahora abre los detalles de la pila y explóralos. En la pestaña Recursos, verás que no se ha implementado nada, excepto un recurso llamado CDKMetadata, que contiene solo algunos detalles de configuración inicial de nuestra pila.

Paso 2: Crear la cola SQS

Una vez que todo esté configurado, puedes crear tu primer recurso real, que será una cola SQS.

2.1 – Agregar la cola a la pila

Para empezar, archiva lib\pila-de-ejemplo-punto-a-punto.ts Abierto.

Según la versión de la plantilla del CDK, es posible que ya se hayan añadido algunas declaraciones de importación, como aws-cdk-lib/aws-sqs, en un comentario. De ser así, elimine los símbolos de comentario // delante de import * as sqs from 'aws-cdk-lib/aws-sqs'; de lo contrario, añádalos usted mismo para que las tres primeras líneas del archivo se vean así:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';

Ahora los comentarios en clase. Pila de ejemplos de punto a punto Elimina y reemplaza el siguiente código y guarda los cambios:

const queue = new sqs.Queue(this, 'Queue', {
queueName: 'MyQueue',
});
2.2 – Implementar la cola

Para implementar la cola, ejecute el siguiente comando en el directorio de su proyecto:

cdk deploy

Ahora puede monitorear el proceso de implementación en la salida de la terminal y debería completarse después de uno o dos minutos.

Una vez completada la implementación, vaya a la lista de colas de SQS en la consola de administración de AWS y busque una cola llamada SqsTutorialStack-Queue:

2.3 – Verificar la cola de Implementados

Vaya al panel de SQS en la consola de administración de AWS y revise la lista de colas. Si no encuentra su cola, asegúrese de estar en la región correcta.


Paso 3: Crea la función Productor y conéctala a la cola

3.1 – Escribir el código fuente de la función generadora

Usaremos JavaScript para la función Lambda y almacenaremos el código fuente en una carpeta propia dentro de la aplicación CDK. Posteriormente, haremos referencia a esta carpeta desde nuestra pila CDK para que pueda empaquetar, cargar e implementar automáticamente el contenido en AWS.

Asegúrese de estar en el directorio del proyecto y cree los siguientes directorios y el archivo en sí:

mkdir lambda-src
mkdir lambda-src/producer
touch lambda-src/producer/send_message_to_sqs.js

La estructura del directorio de su proyecto ahora debería verse así:

point-to-point-example/
├── bin/
│ └── point-to-point-example.ts
├── lambda-src/
│ └── producer/
│ └── send_message_to_sqs.js
├── lib/
│ └── point-to-point-example-stack.ts
└── ...

Nuevo archivo creado. lambda-src/producer/enviar_mensaje_a_sqs.js Ábrelo en tu editor y agrega el siguiente código:

const sqs = require("@aws-sdk/client-sqs");
// Create an Amazon SQS service client
const client = new sqs.SQSClient();
exports.handler = async (event, context) => {
// Create a message, including the function's name from
// its execution context
const myMessage = 'Hello World from ' + context.functionName
// Get the queue URL from the execution environment
const queueUrl = process.env.SQSQueueUrl
// Create a SendMessageCommand containing the message
// and the queue URL
const command = new sqs.SendMessageCommand({
MessageBody: JSON.stringify({ message: myMessage }),
QueueUrl: queueUrl
});
// Send the message and return the result 
const result = await client.send(command);
return result;
}

Este es un controlador de función Lambda simple que envía un mensaje a nuestra cola SQS y devuelve el resultado.

Tenga en cuenta que, dado que no sabemos necesariamente qué cola usar al compilar esta función, o que podríamos querer cambiarla más adelante sin tener que modificar el código de la función, recuperamos la URL de la cola del entorno de ejecución. De esta forma, podemos definirla dinámicamente durante la implementación de la función Lambda en la pila del CDK.

3.2 – Agregar la función Productor a la pila

Para crear una función Lambda real en AWS, debe agregarla a la pila. Para ello, abra lib/point-to-point-example-stack.ts.

Primero, agregue otra declaración de importación en la parte superior del archivo:

import * as lambda from 'aws-cdk-lib/aws-lambda';

Luego agregue el siguiente fragmento dentro del constructor, debajo de la cola:

const producerFunction = new lambda.Function(this, 'Producer', {
functionName: 'Producer',
runtime: lambda.Runtime.NODEJS_18_X,
code: lambda.Code.fromAsset('lambda-src/producer'),
handler: 'send_message_to_sqs.handler',
environment: {
SQSQueueUrl: queue.queueUrl,
}
});

Esto crea una función, paquetes y contenidos del directorio lambda-src/producer, y configura la función para usar el controlador definido en send_message_to_sqs.js cuando se llama.

También establece dinámicamente la variable de entorno SQSQueueUrl en la URL real de la cola SQS para que se pueda acceder a ella desde dentro de la función usando process.env.SQSQueueUrl.

3.3 – Licencia de ejecución del productor

Cada función Lambda requiere algunos permisos IAM básicos, que el CDK proporciona de manera predeterminada mediante un rol de ejecución básico.

Sin embargo, nuestra función de productor necesita permisos adicionales para enviar mensajes a la cola. Afortunadamente, en CDK no necesitamos administrar las políticas de IAM manualmente. Podemos usar el método grantSendMessages de la cola SQS con nuestra función Lambda.

Para ello, agregue la siguiente línea debajo de su producerFunction:

queue.grantSendMessages(producerFunction);
3.4 – Implementar la función de productor

Para implementar la función junto con su código fuente, ejecute el siguiente comando en el directorio del proyecto:

cdk deploy

Esto prepara la implementación de cualquier recurso nuevo o modificado.

Si algún cambio en su pila requiere crear o modificar permisos de IAM, CDK le solicitará que vuelva a examinar estos cambios por razones de seguridad.

En la imagen a continuación, puede ver que CDK desea realizar tres cambios que afectan los permisos de IAM:

  • Permitir que el servicio Lambda (lambda.amazon.aws) asuma el rol de ejecución asociado a la función Productor.
  • Agregue los permisos necesarios directamente para permitir que el rol ejecutivo acceda y envíe mensajes a la cola de SQS.
  • Agregue una política administrada con permisos iniciales para la función de ejecución.


Escriba y para confirmar y CDK implementará la nueva función Lambda junto con su rol IAM.

3.5 – Probar el rendimiento del productor

Después de ejecutar la función, vaya a la lista de funciones en el panel de AWS Lambda.

El nombre de la función es el mismo que definimos en la pila: Productor. Si no encuentra la función, asegúrese de estar en la región correcta.

Haga clic en el nombre de la función para abrir sus detalles e ir a la sección del código fuente.

La carpeta del explorador de archivos a la izquierda contiene un archivo llamado send_message_to_sqs.js.

Haga doble clic en el nombre del archivo para abrir su fuente, donde podrá ver que es una copia exacta del archivo que creamos en la carpeta lambda-src/producer en nuestro proyecto CDK.


Ahora vamos a configurar un evento de prueba.

Para ello, haga clic en el botón "Probar". Si aún no ha configurado un evento de prueba, se abrirá la página "Configuración de prueba". Introduzca el nombre del evento (por ejemplo, "test-event") y haga clic en "Guardar".

Una vez configurado el evento de prueba, haga clic en Probar nuevamente, lo que llamará directamente a la función Lambda.

Esto creará una pestaña de Resultados de ejecución que contiene la respuesta:

{
"$metadata": {
"httpStatusCode": 200,
"requestId": "cb033b2a-1234-5678-9012-66188359d280",
"attempts": 1,
"totalRetryDelay": 0
},
"MD5OfMessageBody": "b5357af0c1c816b2d41275537cc0d1af",
"MessageId": "4a76e538-1234-5678-9012-749f0f4b9294"
}

¿Recuerdas el fragmento de código en la función Lambda?

const result = await client.send(command);
return result;

El objeto JSON en los resultados de ejecución anteriores es exactamente lo que SQS devolvió como respuesta a client.send(command), incluida información interesante como “httpStatusCode”: 200, lo que significa que la cola recibió el mensaje correctamente.

3.6 – Recuperación manual de mensajes de SQS

Actualmente, la cola no está conectada al consumidor, por lo que no se recibirá el mensaje. Sin embargo, podemos recuperarlo manualmente.

Vaya al panel de SQS, haga clic en la cola para abrir su página de detalles y haga clic en el botón Enviar y recibir mensajes.

En la página siguiente, vaya a la sección Recibir mensajes y haga clic en el botón Sondear mensajes, que debería mostrar todos los mensajes que están circulando actualmente, incluidos los mensajes que su función de generación envió cuando la probó:


Haga clic en el ID del mensaje para abrirlo. Debe contener el siguiente texto:

{"message":"Hello World from Producer"}

¡Felicitaciones! Ha implementado y probado correctamente una función Lambda que envía mensajes a una cola de SQS.

A continuación, creamos la función de consumidor y la configuramos para que se llame automáticamente cada vez que llegue un nuevo mensaje a la cola.

Paso 4: Crea la función Consumidor y conéctala a la cola

4.1 – Escribir el código fuente de la función del consumidor

El código de la función del consumidor se almacena en su propia carpeta dentro de lambda-src, de modo que el CDK pueda empaquetarlo automáticamente y cargarlo en la nueva función Lambda.

Asegúrese de estar en el directorio del proyecto (no en bin/ o lib/) y cree el siguiente directorio con el archivo fuente:

mkdir lambda-src/consumer
touch lambda-src/consumer/receive_message_from_sqs.js

Abra lambda-src/consumer/receive_message_from_sqs.js en su editor e ingrese el siguiente código:

exports.handler = async (event) => {
// Retrieve the message from the event and log it to the console
const message = event.Records[0].body;
console.log(message);
}

Este es un controlador de función Lambda muy simple que abre el mensaje SQS y lo imprime en el informe.

4.2 – Agregar la función Consumidor a la pila

Para crear una función Lambda real en AWS, debe agregarla a la pila. Para ello, abra lib/point-to-point-example-stack.ts.

Agregue el siguiente fragmento dentro del productor, debajo de queue.grantSendMessages(producerFunction):

 const consumerFunction = new lambda.Function(this, 'Consumer', {
functionName: 'Consumer',
runtime: lambda.Runtime.NODEJS_18_X,
code: lambda.Code.fromAsset('lambda-src/consumer'),
handler: 'receive_message_from_sqs.handler'
});

Esta función de consumidor crea los paquetes y contenidos del directorio lambda-src/consumer y configura la función para utilizar el controlador definido en receive_message_from_sqs.js cuando se la llama.

4.3 – Agregar la cola SQS como fuente de eventos a The Consumer

Queremos que esta función se active cada vez que haya un nuevo mensaje en nuestra cola. Para ello, debemos agregar la cola como origen de eventos para la función y otorgarle todos los permisos necesarios para consumir mensajes.

Primero, agregue otra declaración de importación en la parte superior del archivo:

import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';

A continuación, agregue las siguientes dos líneas debajo de la definición de customersFunction:

consumerFunction.addEventSource(new SqsEventSource(queue));
queue.grantConsumeMessages(consumerFunction);
4.4 – Implementación de la función de consumidor

Para implementar la función junto con su código fuente, ejecute el siguiente comando en el directorio del proyecto:

cdk deploy

Esto prepara la implementación de cualquier recurso nuevo o modificado y, nuevamente, le solicita que vuelva a verificar los nuevos permisos de IAM.

Escriba y para confirmar y CDK ejecutará la nueva función Lambda junto con su rol de ejecución y la adjuntará a la cola SQS.

Una vez finalizada la implementación, todo estará listo y conectado. Veamos si funciona.

Paso 5 – Pruebas de extremo a extremo de la aplicación

Para probar la aplicación, llamamos manualmente a la función productora para enviar otro mensaje a la cola. Luego, revisamos los registros de ejecución de la función consumidora para comprobar si ejecutó y procesó el mensaje automáticamente.

5.1 – Llamar a la función Productor

Siga los pasos mencionados en 3.5: Probar la función de productor para volver a llamarla. A continuación, un breve resumen:

  • Vaya a la lista de funciones en el panel de AWS Lambda.
  • Abra la función Productor haciendo clic en su nombre.
  • Vaya a la sección de código fuente.
  • Haga clic en el botón Probar.
  • Asegúrese de que la función se ejecute correctamente.
5.2 – Consultar el informe de rendimiento del consumidor

Regrese a la lista de funciones en el panel de AWS Lambda y esta vez abra la función Consumidor.

Desplácese hacia abajo, abra una pestaña llamada Monitor, dentro de esta pestaña, abra la pestaña Registros y eche un vistazo a Invocaciones recientes, donde debería encontrar un enlace al último LogStream de la función.


Después, haz clic en el enlace "Flujo de registro". Esto mostrará la entrada del registro, lo cual puede resultar un poco confuso si no estás familiarizado con el formato.

Simplemente busque la entrada justo en el medio entre estos dos, comenzando con START RequestId: … y END Request ID: ….

Haga clic en la flecha para expandir la entrada donde debería encontrar el mensaje original:

Resultado

¡Felicitaciones! Has creado todo lo necesario para configurar la mensajería asincrónica punto a punto entre dos funciones Lambda mediante SQS.

SQS ofrece muchas más funciones, como categorizar mensajes, garantizar su orden y enviar automáticamente los mensajes incorrectos a una cola de entregas pendientes (DLQ). Si desea obtener más información, consulte la Guía para desarrolladores de Amazon SQS.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

También te puede gustar