Las aplicaciones que manejan un alto volumen de imágenes necesitan formas eficientes de procesarlas tan pronto como se suben al sistema. El procesamiento directo puede sobrecargar los servidores y crear cuellos de botella. Por eso, es necesario un enfoque distribuido y escalable para manejar cargas de trabajo variables sin sacrificar el rendimiento.
Click here for the english version
Arquitectura
La solución utiliza una arquitectura serverless y event-driven que garantiza escalabilidad y resistencia:
- Las imágenes se suben a un bucket de entrada en S3.
- Los eventos de subida ejecutan una función Lambda.
- Lambda envía los metadatos a una cola SQS.
- Una Lambda de procesamiento consume los mensajes de la cola SQS.
- Las miniaturas se generan y se almacenan en el bucket de salida.
Este enfoque desacopla las etapas de subida y procesamiento de imágenes, permitiendo que el sistema maneje picos de carga de manera eficiente.
Servicios AWS Utilizados
- Amazon S3: Funciona como origen para las imágenes originales y destino para las miniaturas procesadas.
- Amazon SQS: Actúa como message broker para desacoplar las etapas de subida y procesamiento.
- AWS Lambda: Proporciona capacidad de cómputo serverless para el manejo de eventos y procesamiento de imágenes.
- AWS IAM: Gestiona los permisos y asegura el acceso seguro a los recursos de AWS.
Implementación Técnica
Subida de Imágenes
- Un usuario sube una imagen al bucket de entrada en S3.
- Una notificación de evento de S3 activa la primera función Lambda.
- Esta función Lambda construye un mensaje que contiene los metadatos de la imagen (ej: bucketName, key).
- Los metadatos se publican en una cola SQS.
Procesamiento
- Una segunda función Lambda monitorea constantemente la cola SQS en busca de nuevos mensajes.
- Al recibir un mensaje, la función Lambda:
- Descarga la imagen del bucket de entrada.
- Procesa la imagen usando la librería Sharp para generar las miniaturas.
- Sube las miniaturas de regreso al bucket .
- Una vez que el proceso termina exitosamente, el mensaje correspondiente se elimina de la cola SQS.
Manejo de Errores
- Dead Letter Queue (DLQ): Los mensajes que fallan en el procesamiento después de varios intentos se mueven a una DLQ para análisis posterior.
- CloudWatch Logs: Los logs capturan los pasos detallados del procesamiento e información de errores para debugging.
- Reintentos Automáticos: Los errores transitorios activan reintentos automáticos basados en las políticas de SQS.
Infraestructura como Código con AWS CDK
Veamos en detalle la implementación de la infraestructura principal en nuestro stack de AWS CDK:
S3 Bucket
const bucket = new Bucket(this, 'AwsSqsThumbnailGeneratorBucket', {
bucketName: 'sqs-thumbnail-generator-bucket',
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
versioned: true
});
Creamos un bucket de S3 con versionamiento habilitado para almacenar imágenes originales y miniaturas generadas. El bucket está configurado para la eliminación automática de objetos para simplificar la eliminación del stack, esto no se recomienda en producción.
Queues
const dlq = new Queue(this, 'AwsSqsThumbnailGeneratorDeadLetterQueue', {
queueName: 'thumbnail-generator-dlq',
retentionPeriod: cdk.Duration.days(10)
});
const queue = new Queue(this, 'AwsSqsThumbnailGeneratorQueue', {
queueName: 'thumbnail-generator-queue',
visibilityTimeout: cdk.Duration.seconds(60),
deadLetterQueue: {
queue: dlq,
maxReceiveCount: 3
}
});
Configuramos dos queues (colas):
Un queue principal para procesar imágenes
Una Dead Letter Queue (DLQ) para manejar intentos fallidos de procesamiento
Los mensajes se mueven a la DLQ después de 3 intentos fallidos
S3 to SQS Integration
bucket.addEventNotification(
EventType.OBJECT_CREATED,
new SqsDestination(queue),
{prefix: 'uploads/'}
);
Esta configuración envía automáticamente un mensaje a SQS cada vez que se sube un nuevo archivo al directorio uploads/
en nuestro bucket de S3.
Libreria Sharp
const sharpLayer = new LayerVersion(this, 'SharpLayer', {
code: Code.fromAsset(path.join(__dirname, './layers/sharp.zip')),
compatibleRuntimes: [Runtime.NODEJS_LATEST],
compatibleArchitectures: [Architecture.ARM_64]
});
Necesitamos la librería Sharp para procesar imágenes. Creamos una Lambda Layer con la librería y la adjuntamos a nuestra función de procesamiento. Esto asegura que la librería esté disponible para la función en tiempo de ejecución.
Esta capa específica está construida para la arquitectura ARM64, que es la arquitectura utilizada por los procesadores AWS Graviton2. Está optimizada para rendimiento y ahorro de costos. Sharp Layer
Thumbnail Generator Lambda
const generator = new NodejsFunction(this, 'AwsSqsThumbnailGeneratorProcessor', {
functionName: 'thumbnail-generator-processor',
runtime: Runtime.NODEJS_LATEST,
handler: 'handler',
entry: path.join(__dirname, './functions/thumbnail-generator.ts'),
layers: [sharpLayer],
architecture: Architecture.ARM_64,
timeout: cdk.Duration.seconds(60),
environment: {
QUEUE_URL: queue.queueUrl
}
});
generator.addEventSource(new SqsEventSource(queue));
Definimos una función Lambda que procesa mensajes del SQS. La función se activa con nuevos mensajes en la cola y genera miniaturas usando la librería Sharp.
El código de la función está definido en el archivo thumbnail-generator.ts
, que es responsable de descargar, procesar y subir imágenes.
IAM Policies
queue.addToResourcePolicy(new PolicyStatement({
effect: Effect.ALLOW,
principals: [new ServicePrincipal('s3.amazonaws.com')],
actions: ['sqs:SendMessage'],
resources: [queue.queueArn],
conditions: {
ArnLike: {
'aws:SourceArn': bucket.bucketArn,
},
},
}));
bucket.grantReadWrite(generator);
queue.grantConsumeMessages(generator);
Definimos políticas IAM para permitir que el bucket de S3 envíe mensajes al queue y otorgamos a la función Lambda de procesamiento acceso de lectura/escritura al bucket y permiso para consumir mensajes del queue.
Cómo Utilizarlo
Si quieres probar este proyecto, sigue estos pasos:
- Clona el Repositorio: AWS SQS Thumbnail Generator.
-
Actualiza la Configuración: Modifica los detalles de cuenta y región en el archivo
/bin/aws-sqs-thumbnail-generator.ts
. -
Configura los Tamaños de Miniatura: Ajusta los tamaños en el archivo
/functions/thumbnail-generator.ts
a tus necesidades. - Despliega la Infraestructura: Utiliza AWS CDK para desplegar los recursos necesarios.
- Prueba el Flujo: Sube una imagen al bucket de entrada en S3 y observa cómo se generan y almacenan automáticamente las miniaturas en el bucket de salida.
Conclusión
El AWS SQS Thumbnail Generator es un excelente ejemplo de cómo aprovechar la arquitectura serverless para construir flujos de trabajo escalables, eficientes y resilientes. Al desacoplar procesos y utilizar servicios como SQS, Lambda y S3, este proyecto demuestra cómo manejar tareas intensivas en recursos de manera sencilla.
Este proyecto puede expandirse añadiendo funcionalidades como reconocimiento de imágenes, extracción de metadatos o integración con otros servicios de AWS. Las posibilidades son infinitas, y la escalabilidad y flexibilidad de la arquitectura serverless la convierten en la opción ideal para este tipo de aplicaciones.
Top comments (0)