Aumenta la disponibilidad de tus sistemas Legacy
Tags: aws, legacy, serverless, availability
Published: 2024-07-09 07:00:00

Muchos de nosotros trabajamos con servicios legacy o bien servicios que no son capaces de escalar correctamente, ya sea por problemas de diseño o por requerimientos técnicos. Estos sistemas que tienen esas dificultad para escalar son mas propensos a sufrir paradas de servicio, lo que supone un gran problema, sobre todo para los sistemas que reciben notificaciones asíncronas de otros sistemas.
Es en este último tipo de comunicaciones en el que nos vamos a centrar en este artículo.

Si tenemos un sistema, obsoleto, legacy, mal construido o bien que no hemos podido perfeccionarlo todo lo que hemos podido, y que recibe comunicaciones asíncronas, las cuales no podemos perder ya que cada mensaje no recibido supone una pérdida de información, no hace falta que invirtamos una gran cantidad de tiempo y/o dinero en actualizar nuestro sistema. Podemos aplicar una solución muy sencilla, muy barata y muy fácil de mantener que resolverá todos nuestros problemas ante posibles caídas. Esta solución también se puede aplicar a instancias de tipo Spot, que únicamente reciben comunicaciones asíncronas, y de esta manera poder tener este tipo de instancias incluso en entornos productivos, reduciendo los costes considerablemente.

## Solución

Nuestra solución se basa en añadir una capa serverless sobre nuestra aplicación, que nos permita gestionar las comunicaciones asíncronas a hacia nuestra API.

![Capa superior a nuestra API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6vfj7bfgm749xo3slro.png)

Este diseño permitirá una comunicación en tiempo real con nuestra API y un backup en caso de caída del servicio que nos permitirá recuperar la comunicación con los mensajes perdidos durante la caída.

## Arquitectura

Para implementar esta solución descrita anteriormente, solo necesitamos implementar 3 servicios muy comunes dentro del catálogo de servicios de AWS

- Amazon API Gateway
- AWS Lambda
- Amazon SQS

![Arquitectura servicios asíncronos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6f6zs8pusnd25ooypb1.png)

Con estos tres servicios conseguiremos una comunicación asíncrona con disponibilidad total (99,9% de disponibilidad cada uno de ellos)

Existe la posibilidad incluso de ahorrarnos uno de los tres servicios descritos anteriormente y hacer uso únicamente de Amazon API Gateway y Amazon SQS.

![Arquitectura servicios asíncronos v2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhuqgsrkitoaqsfim9ym.png)

Este caso no lo recomendamos ya que el mensaje que llega a nuestra API debe tener una estructura determinada para poder ser enviado directamente al servicio de SQS. Con el uso del servicio de Lambda conseguimos una mayor flexibilidad, pudiendo modificar el mensaje, añadir control de excepciones, etc. 

## Comunicación con nuestra API

Ahora toca comunicar la nueva arquitectura con nuestra API. Existen varias opciones para establecer esta comunicación, por un lado podemos enviar los mensajes recibidos directamente a nuestra API o podemos hacer que nuestra API vaya a buscar los mensajes a nuestra servicio de mensajería. Ambas opciones son igualmente válidas y dependería de nuestra solución el usar una u otra opción.

###SQS to API

Esta sería la comunicación mas lógica en un inicio, donde cada mensaje que llega a nuestra nueva capa de servicios serverless es enviada directamente a nuestra API

Y aquí también tenemos dos opciones. En la primera imagen vemos como el mensaje que llega a nuestro servicio de colas puede ser enviado a nuestra API. Amazon SQS permite implementar Listeners dentro de nuestra API que permita recibir los mensajes que se encolan en nuestro servicio.

![Envío de mensajes a nuestra API - Listener](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3orrpi7x5pceli8p5qml.png)

Pero en el caso que la tecnología usada en nuestra API no permita conectarnos a nuestro servicio de SQS a través del Listener, podemos optar por una segunda opción, la cual sería añadir una Lambda que nos permita establecer la comunicación entre nuestro servicio de colas y nuestra API.

![Envío de mensajes a nuestra API - Lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/scf7cxj5u8zdf7stup08.png)


###API to SQS

La segunda opción se trata de delegar la responsabilidad a nuestra API de la lectura de mensajes, es una opción menos usada pero que es efectiva si queremos tener el control de cuanta información queremos procesar o si queremos procesarla a una hora determinada del dia.

![Lectura de mensajes en el servicio de SQS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0gkvcu3igfilc16tbxh4.png)

Otra de las ventajas de esta última opción, es que en el caso de caída de nuestra API, los mensajes no serán leídos, y cuando nuestra API vuelva a estar operativa se volverán a procesar.

Pero entonces, ¿qué pasaría si decidimos implementar la primera de las opciones descritas?

###SQS to API - DLQ

En el caso que nuestra API no esté disponible, hay mecanismos (o configuraciones) que nos permiten reprocesar nuestros mensajes en otro momento. 

Es el caso de las colas DLQ (Amazon SQS Dead Letter Queues), son colas a la que podemos enviar los mensajes fallidos de una cola SQS. Podemos establecer un número de reintentos de lectura en nuestra cola SQS y una vez realizado ese número de reintentos el mensaje de la SQS pasaría automáticamente a la DLQ, cuyo comportamiento es el mismo que el de una SQS.

![SQS Dead Letter Queue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xcd34fzu5lg9qpzhydr.png)

Los mensajes permanecerán en esta cola hasta que nuestra API vuelva a estar disponible, y cuando eso ocurra, podremos volver a leer esos mensajes, ya sea accediendo a la DLQ desde nuestra API

![Lectura de API a DLQ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n569443h908rf87kc4p4.png)

O bien, haciendo uso de una lambda que se encargue de comprobar la disponibilidad de nuestra API y una vez esté disponible sea la encargada de leer y enviar de nuevo los mensajes de la DLQ a nuestra API

![Lectura de API a DLQ - Lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rc0ymlrbwpu2g1fjyv9z.png)

Y con esta simple arquitectura podemos implementar una capa asíncrona y con una disponibilidad del 99,9% sin necesidad de hacer grandes cambios en nuestra API.

En el siguiente post crearemos esta infraestructura con CDK y Python paso a paso y lo tendréis disponible en GitHub para que podáis adaptar y desplegar esta solución en pocos minutos.