Blog de Amazon Web Services (AWS)

Cómo procesar una gran carga y concurrencia de consumos y flujos de ventas sin necesidad de mantener un servidor

Por Claudio Di Salvo, Gerente de Proyectos

La empresa es una multinacional estadounidense productora de agroquímicos y biotecnología, destinados a la agricultura, líder mundial en ingeniería genética de semillas y producción de herbicidas. Recientemente fue adquirida por una empresa químico-farmacéutica alemana, la mayor compra jamás realizada por una compañía de ese país en el extranjero, con lo cual se ha convertido en uno de los tres conglomerados que controlan más del 60% del mercado de semillas y agroquímicos a nivel mundial.Snoop Consulting ayudó a uno de sus clientes implementado las soluciones de AWS e incrementando las funcionalidades de su sistema de facturación.

El Desafío

El sistema de procesamiento de ventas y consumos del cliente maneja una enorme carga y concurrencia de información. Esta información llega desde otros sistemas y se debe gestionar el success or fail para cada transacción.

Uno de los principales desafíos planteaba la necesidad de trabajar de una forma en la cual el cliente no tuviera que mantener un servidor, por lo cual se comenzó a utilizar AWS Lambda.

Por otro lado, se esperaba que la utilización de las funciones Lambda sirvieran para reducir los mensajes fallidos, manejar la concurrencia de datos, eliminar la posibilidad de duplicidad de datos y además mejorar la performance del sistema.

La solución

El sistema se encuentra en producción hace un más de un año, soportando la carga de trabajo sin servidores o contenedores auxiliares, utilizando funciones Lambda para manejar y procesar los flujos de datos centrales del sistema. Solamente se está utilizando de forma auxiliar una instancia EC2 para Jenkins.

Es un sistema asincrónico principalmente compuesto por funciones Lambda, comunicadas por colas SQS (Amazon Simple Queue Service) más SNS (Amazon Simple Notification Service) si el mensaje tiene más de un interesado. Las funciones AWS Lambda se encuentran configuradas sin limitar la concurrencia a un número de instancias específico dejando este manejo de forma automática, solamente se limitaron aquellas funciones que acceden a la base de datos.

También se implementó un dashboard en AWS para el monitoreo de funciones Lambda en Amazon CloudWatch Dashboard con alarmas de duración baja y alta, para alertar si la función tiene baja performance o finalizó por timeout, y para el monitoreo de errores. Para ello hay un ‘topic’ escuchando en SNS y que luego publica el error directamente en Slack, en un canal de monitoreo propio. También se utiliza AWS X-Ray para trackear los mensajes que tienen algún tipo de problema.

Actualmente se siguen incorporando nuevas funcionalidades de manera progresiva.

Trabajando con AWS Lambda

Para el desarrollo del código de las funciones Lambda se utiliza Github enterprise junto con Jenkins para la integración continua y automatización del despliegue desde Github.

En el modelo de solución se debía considerar la posibilidad de mensajes repetidos que podrían llegar a generar datos duplicados. Para evitar esto se creó una biblioteca para verificar si un mensaje ya había sido tratado o no por una función Lambda, esto fue implementado manejando un ID único de transacción.

También se aprovechó la funcionalidad de reintento de las funciones Lambda cuando tienen integración con Amazon SQS, de esa forma se pudo llegar a tener menor cantidad de mensajes fallidos en un mismo proceso.

Las ejecuciones fallidas se reintentan automáticamente un cierto tiempo debido a la integración SQS-Lambda, y si continúa fallando termina en una ‘Dead Letter queue’ y se notifica.

En un principio se comenzaron a utilizar funciones Lambdas con 128 MB de memoria (su valor por defecto). Pero luego modificar este valor y fijarlo en un valor superior se pudo mejorar notoriamente la performance. Para funciones productivas ahora se utilizan al menos 512 MB.

Actualmente la cantidad de funciones Lambda desarrolladas llegan a un total de 160 con un número total estimado de eventos por mes esperados para esas funciones de 240.000 en promedio.

La orquestación completa de la familia AWS integrada

La carga de trabajo se distribuye de la siguiente manera:

  • Amazon API Gateway: como entrada al sistema se utiliza gran parte de los endpoints asociados a una función Lambda con express.js;
  • AWS Lambda: para el procesamiento y persistencia de datos se utiliza AWS Lambda en Node js;
  • Amazon SQS / Amazon Kinesis: como sistema de colas de mensajes;
  • Amazon SNS: como tópicos de difusión de mensajes;
  • Amazon RDS: utilizado con PostgreSql y Amazon Aurora PostgreSql como almacenamientos;
  • Amazon CloudWatch / AWS Xray: utilizados para las alertas y el tracking;
  • Amazon Cloudfront: como un content delivery network (CDN) para las UI’s, almacenadas en Amazon S3;

DIAGRAMAS DE ARQUITECTURA