7 minutos

Algunos consejos para acelerar tu web y afrontar el COVID-19

Todos hemos visto como durante esta alarma sanitaria, el consumo de los servicios de streaming e internet se han disparados hasta niveles nunca vistos hasta ahora. Por un lado es triste la situación general de sanitarios y enfermeros sin suficientes recursos, sin embargo cada uno debe aportar su granito de arena y es un buen momento para adaptar nuestra infraestructura a una gran demanda en poco tiempo y sin previo aviso.

La caída de internet ha sido generalizada en todo el mundo, y a pesar de que los efectos han sido mitigados realmente rápido, esto expone algunos problemas que tenemos a los que no nos hemos enfrentado antes. Además, no solo es el uso masivo de servicios de streaming, juegos online y videoconferencias es lo que está congestionando la red. El hecho de que los mayores anchos de bandas siempre hayan sido destinados a oficinas mientras ahora estamos todos desde nuestras casas confinados, sumado al incremento de ataques DDOS está haciéndome cuestionar si estamos preparados, y de cuánto es la cifra de clientes de esas botnets que hasta ahora permanecía dormidas.

CDN Loadtime from 24th March to 30th March

Incluso las mayores CDN que invierten millones de dólares al año en grandes centros de datos han sufrido durante este confinamiento, aumentando los tiempos de respuestas en casi todas las regiones debido al alto tráfico en la red. A pesar de ello hay que decir que las compañías están escalando sus servicios rápidamente gracias a herramientas en la nube como Kubernetes o Amazon AWS, lo que está permitiendo la mayor expansión de internet en los últimos tiempos.

Existe una gran cantidad de tecnologías en la nube que podría mencionar aquí, pero sería un post eterno lo que no concuerda con título "Algunos consejos para...", así que hare un breve repaso de algunos tips que considero más eficaces y rápidos de implementar.

La mayoría de estos consejos son aplicables a cualquier tipo de sitio web ya esté construido en PHP, Node, Python o HTML y CSS. Principalmente hacen referencia a la infraestructura o a la forma de crear u organizar el código y como desplegarlo.

Optimiza la infraestructura

Es obvio que cuanto mas tiempo pase una petición como IDLE en tus servidores, mas tiempo tardará un cliente en recibir la respuesta. Por eso hacer especial incapié en reducir la cantidad de esfuerzo que hace tu clúster o servidor privado a la hora de procesar cada petición es vital y un tiempo totalmente bien invertido. En mi caso, empecé por reducir la complejidad de niveles en la infraestructura y asegurándome de que los canales de comunicación son lo suficientemente estables y seguros para continuar el despliegue en producción.

Un buen monitoreo y sistema de alertas puede ayudarte a detectar cualquier saturación en tus servicios, posibles single point of failures y sobrecarga en general. Recuerda también que, nginx resuelve mucho más rapido un reverse proxy que una resolución de host típica al sistema de ficheros. Dejo algunos recursos interesantes para la configuración de nginx, SSL, reverse proxies:

CDN

Hacer uso de una CDN puede suponer una reducción de entre un 30 y 80% del tráfico a tu servidor origen (dependiendo del tipo de contenido y configuración TTL). Y esto se consigue gracias a que los servidores CDN actúan como intermediarios entre tu servidor origen y los clientes, de manera que el tráfico primero pasa por sus centros de datos con grandes capacidades de cacheamiento de assets y compresión, y sólo en caso de no encontrarse allí lo que el usuario busca, se devuelve la petición a tu servidor y queda cacheada para la siguiente vez que se solicite.

Hay muchos servicios pero la mayoría se configuran fácilmente cambiando los servidores de DNS de tu dominio apuntando a los facilitados por tu proveedor CDN. Revisa las opciones que proveen ya que suelen incluir minificado de archivos y compresión Gzip, además de distintas opciones de seguridad para impedir el acceso a través de ciertos puertos, rutas o configurar la expiración de la caché del navegador así como inyectar cabeceras. Presta especial atención al valor de la TTL. Dependiendo del tráfico y el tipo de contenido que sirvas te interesa mantenerlos durante más tiempo o menos.

Algunos de los mejores proveedores:

Fuente: CDNPerf Report (25-04-2020)

Además una CDN proporciona seguridad ya que mitigan la mayoría de ataques DDOS que podrían alcanzar tu servidor origen. Lo que podría impactar directamente en el rendimiento y calidad del servicio que reciben tus clientes. Considera una CDN de pago en caso de que tu tráfico o datos transferidos supere el límite del plan gratuito.

Conteneriza tu aplicación

En mi caso me encontré con un proyecto con algo de tiempo funcionando de manera monorepo y dependiendo aún de la infraestructura en local para su desarrollo. Por ello, aunque reconozco que lleva algo de esfuerzo, trata de Dockerizarlo lo antes posible para sacar provecho de todas las ventajas que te ofrecen los contendores (sí, ya las conoces). Luego todo tu equipo podrá reusar la misma configuración sin interferir en su trabajo y promueve un desarrollo continuo. Recuerda usar Docker Secrets para las contraseñas y api keys en lugar de variables de entorno, ya que éstas son visibles desde los logs. Una vez hecho todo esto, en la infraestructura nunca habrá sido más fácil crear réplicas de ese stack de trabajo ya sea en Kubernetes, Gcloud, Amazon EKS o Docker Swarm.

Considera esto la prioridad más baja de todas las anteriores. A pesar de que supone una mejora notable en el rendimiento y te ofrece la posibilidad de escalar nodos rápidamente, también es posible conseguir esto por ejemplo utilizando clústers. Son alternativas más caras y por tanto la nube y los microservicios es la opción principalmente escogida por los responsables de Devops.

Busca alternativas a tus servicios de terceros

Debemos replantearnos los ingenieros de software la manera en la que entregamos nuestros proyectos. Hasta ahora era muy común crear un stack de trabajo con un único servicio de mailing, autentificación, transcodificación de vídeo, o cualquier otra cosa que se te ocurra donde externalizamos una parte de nuestro proyecto. De manera que, si muchos desarrollos dependen de la misma plataforma, en situación de alto tráfico existe la posibilidad de que su red se vea saturada, por tanto debemos ser capaces de cambiar a otro servicio de emergencia en unos pocos clicks.

Prepara una estrategia, parametriza lo que falte y crea una cuenta alternativa para esos servicios externos de los que tu proyecto se pueda ver afectado en caso de una caída repentina, y que escapa a tu control. Así serás capaz de dar una respuesta a tus clientes y mantener una alta disponibilidad más allá de lo que suceda en tu propia infraestructura.

Recoge y analiza los datos

Para mantener el buen estado de salud de nuestros sistemas, es fundamental estar informados en todo momento de errores críticos o acumulados en caso de ser recurrente. Estos logs serán muy útiles para analizar las carencias en nuestra infraestructura o software, o cuellos de botella que impiden lidiar con muchas peticiones en un corto periodo de tiempo.

Si tu proyecto está basado en microservicios es posible que te interese unificar la salida de logs en un único punto común. Existen herramientas abiertas como Kafka que realizan muy bien esta labor, permitiendo leer, procesar y almacenar mensajes desde diversas fuentes. Si optas por algo más avanzado servicios como Metrictank, Datadog o Prometheus son buenas alternativas para centralizar tus logs en un sólo lugar y en la nube. También es recomendable crear tests de carga para comprobar hasta donde es capaz de llegar tu servicio, yo utilizo la herramienta Load Impact por su sencillez y porque cuenta con un plan gratuito donde empezar a hacer pruebas.

Sin duda es una situación excepcional, por tanto tener datos de rendimiento y un análisis previo para futuras emergencias o estados de alarma puede ser beneficioso ya que tendremos el conocimiento de qué áreas se van a ver afectadas principalmente y cómo. Y evitar así situaciones como esta:

1.0