¿Te has preguntado cómo escalar una aplicación sin necesidad de tener que entrar en la complejidad de utilizar microservicios?
Bueno a este mismo problema se enfrentaba uno de nuestros clientes, ya que estaba creciendo exponencialmente en tráfico y su aplicación debía escalar en poco tiempo y el core de la aplicación no podía ni disponía del tiempo suficiente para descomponerse en microservicios.
En este post te contamos cómo nos enfrentamos, resolvimos esta problematica y descartamos Kubernetes como opción para escalar esta aplicación.
Análisis del problema
Cuando nuestro cliente contactó con nosotros, tenía los siguientes problemas:
- Una infraestructura que no soportaba la carga de tráfico que le llegaba.
- Caídas constantes del sistema.
- Lentitud y degradación de la aplicación.
- Alta latencia en clientes principalmente de zonas geográficas lejanas a la infraestructura del cliente.
- Imposibilidad de escalar automáticamente.
- Necesidad de implantar una solución factible y en un plazo corto de tiempo.
- Cambio de infraestructura sin o con el mínimo downtime.
- Imposibilidad de descomponer el core de la aplicación en microservicios.
Este último punto, pocas veces se valora ya que uno de los primeros impulsos que nos hemos encontrado en diferentes clientes. Es el de pasar todo el core de su infraestructura de un monolito a Kubernetes, por ejemplo. Sin valorar siquiera todo el tiempo, complejidad y dificultad que eso implica tanto a la propia aplicación como a todo el equipo de ingeniería. Aunque esto lo comentaremos en otro post.
Siguiendo con la infraestructura, el cliente tenía algo como esto:
Plan de migración
Frontend
Lo primero que decidimos hacer es separar el Frontend del Backend, de esta forma quitaríamos carga a los servidores y sobre todo añadiríamos dos componentes fundamentales para cualquier aplicación que requiere atender un tráfico medio/alto y que además atiende a clientes de forma internacional.
- Un sistema de caché de los ficheros estáticos que se entregan a cliente (.css, .js, .png, etc)
- Una CDN capaz de bajar la latencia en la respuesta de la aplicación.
Por tanto para este caso, utilizamos el servicio de AWS llamado CloudFront.
Backend
Aunque quitamos la carga del Frontend, los servidores seguían teniendo la necesidad de escalar y sobre todo se tenía la necesidad de hacerlo de forma automática. Ya que al tener clientes internacionales, los picos de carga eran constantes las 24h del día.
Por ello se recurrió a una funcionalidad de AWS que se encuentra dentro del servicio de EC2, los grupos de autoscaling.
Un grupo de autoscaling es una funcionalidad capaz de gestionar un conjunto de servidores, mediante verificaciones de estado, políticas de escalado, entre otras funciones. Todos los servidores pertenecientes a un grupo de autoscaling tienen las mismas características:
- Misma capacidad de cómputo (CPU, RAM, red, disco, etc)
- Mismo sistema operativo y paquetes instalados
- Mismos permisos y etiquetas.
Todo esto es posible gracias a que los servidores que se crean dentro de un grupo de autoscaling provienen de la misma AMI (servicio de AWS que permite crear una imagen de un servidor)
De esta forma, podemos escalar, aumentando y bajando el número de servidores que atiende el backend automáticamente dependiendo de las necesidades de la propia aplicación.
¿Cómo sabe el grupo de autoscaling cuándo debe aumentar o disminuir el número de servidores?
Esto es debido a que en los grupos de autoscaling podemos configurar:
- Escalados dinámicos que nos permite escalar en base a:
- Una métrica que configuremos en Amazon CloudWatch (Por ejemplo, % de uso de CPU).
- Un escalado por pasos, el cual se basa en un conjunto de ajustes y sistemas de alertas.
- Un escalado simple, el cual escala en base a un único ajuste y además añade un cooldown entre cada escalado que realiza.
- Escalados predictivos el cual es adecuado en situaciones de:
- Tráfico cíclico.
- Patrones recurrentes de cargas de trabajo intermitentes.
- Aplicaciones que tardan mucho tiempo en inicializarse.
- Escalados programados los cuales nos permiten indicar una hora y fecha exacta donde queremos que nuestra infraestructura suba o baje en capacidad.
Os dejamos más información en la documentación del propio AWS.
Infraestructura final
Todos estos cambios dieron como resultado una infraestructura como la siguiente:
Dadas las necesidades de la aplicación, decidimos configurar escalados automáticos en base al consumo de CPU, indicando un número máximo y mínimo de servidores. La regla indicada para este escalado es algo parecido a esto:
- Si el consumo de CPU supera el 50% durante un periodo de tiempo. El grupo de autoscaling deberá ir sumando servidores hasta que llegue al máximo número indicado.
- Si el consumo de CPU está por debajo del 50% durante un periodo de tiempo. El grupo de autoscaling deberá ir disminuyendo el número de servidores hasta llegar al mínimo indicado.
Además, dado que uno de los picos más importantes que tenía la aplicación se producía siempre a una hora concreta, decidimos también crear un escalado programado.
Todos estos cambios, solucionaron en gran medida todos los problemas que tenía nuestro cliente con su infraestructura.
Hoy en día, aunque se han ido añadiendo otros componentes y servicios, el core de la capa de aplicación se sigue sirviendo como se indica en el último esquema.
Algunos datos curiosos de lo que es capaz esta infraestructura:
- Sirve millones de peticiones y usuarios en todo el mundo.
- La latencia de respuesta de la aplicación ahora es inferior a los 400 milisegundos a pesar de tener clientes internacionales.
- Mantiene unos costes ajustados ya que únicamente aumenta el poder de cómputo en los picos de carga y se mantiene al mínimo cuando tiene posibilidad de hacerlo.
Como verás en este post no hemos hablado de una capa fundamental, la capa de datos. Estamos preparando un nuevo post donde hablaremos específicamente de esto ya que de por sí es un tema extenso y queremos cubrirlo al completo.
Esperamos que te haya gustado este post y sobre todo te ayude a valorar alternativas a la hora de plantear una migración a una infraestructura que sea capaz de escalar automáticamente.