NestJS sin servidor con AWS lambda

NestJS sin servidor con AWS lambda: mejore el rendimiento con la carga diferida

NestJS — En este artículo, primero, veremos qué es la arquitectura sin servidor, el inicio en frío y el inicio en caliente y cómo podemos mejorar el rendimiento de la aplicación sin servidor con carga diferida. Por lo tanto, nuestro enfoque prin cipal no es implementar la aplicación en AWS lambda, tal vez podamos tener un artículo separado al respecto.

NestJS

¡Quizá se pregunte por qué se refieron al backend en el tweet! Sí, eso se debe a que NestJS está inspirado en Angular y Angular viene con módulos de carga diferida listos para usar. Aunque, en el backend, solo tiene sentido en una arquitectura serverless. Es por eso que el creador de NestJS agregó esta función recientemente en la versión 8.


Arquitectura sin servidor

Para entender esto, describámoslo con los servicios de AWS. En una palabra muy simple, en AWS EC2 paga en función de las horas que utiliza una instancia. Aunque puede escalar esta arquitectura con la ayuda de Docker y ECS o EKS, a veces no solo no desea pasar por infraestructuras y configuraciones subyacentes, sino que también desea pagar, ya que su código en realidad se ejecuta en el servidor. .

Esto puede ser un poco confuso, así que déjame explicarte con un ejemplo. Supongamos que tiene un producto MVP y, al principio, desea pagar por un servidor cuando un usuario llama a su API y consume sus recursos en lugar de pagar por todo el servidor. Por otro lado, desea escalarlo automáticamente sin tener mucho dolor. En este caso, AWS tiene un servicio llamado Lambda que implementó el marco sin servidor para usted.

Arranque en frío y arranque en caliente

Ahora entendemos que cada vez que nuestro servidor no se usa, en realidad ya no se ejecuta. Entonces, la próxima vez, cuando un nuevo usuario visite nuestra aplicación, lambda iniciará nuestro servidor bajo demanda.

Esto significa que tan pronto como un usuario envíe una solicitud a la puerta de enlace API (que, por cierto, está integrada con lambda), nuestra aplicación NestJS comenzará desde el principio. Llamamos a este proceso un “arranque en frío” que ocurre para cada usuario cada vez que envía la solicitud.

Pero las funciones lambda no eliminan el servidor inmediatamente después de que se da la respuesta al usuario. Mantienen el servidor en línea durante unos minutos. Durante estos pocos minutos, si alguien envía una solicitud, el servidor responde más rápido porque no se cae, por lo que llamamos a esto un “arranque en caliente”.

Entonces, puede decir que si nuestra aplicación crece, tomará un par de segundos (tal vez 5 o 10) para servir la aplicación NestJS y eso es demasiado para una sola solicitud, y el punto es ejecutar una aplicación monolítica como una función sin servidor típicamente no tiene mucho sentido, pero de todos modos, si tiene varios módulos en su función lambda sin servidor, debe usar la función de carga diferida. Antes de pasar por esta función, repasemos algo.


Requisitos previos para la carga diferida: proveedores asíncronos

Ya hemos hablado de los proveedores en este artículo, pero les voy a dar un ejemplo muy rápido y simple:

@Module({
  providers: [
    {
      provide: 'MY_TIMEOUT',
      useFactory: () => {
        return new Promise((resolve) => {
          setTimeout(() => { 
            resolve(true)
          }, 10000);
        })
      },
      // inject: [...],
    };
  ],
})

En el ejemplo anterior, MY_TIMEOUT es un proveedor que se resolverá después de 10 segundos. Todos los proveedores se ejecutan de forma asincrónica, lo que significa que este proveedor no bloqueará a otros proveedores, por lo que comenzarán a ejecutarse simultáneamente, pero la aplicación NestJS se iniciará después de que se resuelvan todas las dependencias. Por lo tanto, es posible que tenga otros proveedores, por ejemplo, conectándose a Redis, etc., que deberían resolverse antes de que NestJS inicie la aplicación.


Usar módulos de carga lenta

Dijimos que puede tomar mucho tiempo para un arranque en frío. Digamos que no necesitamos que nuestros proveedores anteriores se resuelvan para una de nuestras llamadas API (que esperará un inicio en frío). ¿Qué debemos hacer?

Sí, la respuesta es usar módulos de carga lenta. Esto significa que cargamos un módulo (y sus dependencias, que son proveedores) solo cuando es necesario. Digamos que tenemos un proveedor (en este caso es una clase) como el que teníamos antes en uno de nuestros módulos que tarda 10 segundos en resolverse, así es como hacemos que se cargue con pereza:

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}

Además, hay otra forma de cargarlos de forma perezosa si su aplicación NestJS es una aplicación independiente. Por lo tanto, puede consultar aquí para obtener más información.

Mejore el rendimiento con el paquete web

Puede usar webpack para agrupar su aplicación en un único archivo JavaScript ejecutable. En este caso, su tiempo de arranque en frío disminuirá. Para implementar esto, puedes consultar aquí.


Hasta ahora entendimos algunos conceptos y pudimos mejorar el rendimiento de nuestra aplicación sin servidor que se puede implementar en AWS lambda. Espero que lo hayan disfrutado. No dude en agregar comentarios si tiene algo que compartir o preguntar.


Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre Laravel:

 

Recent Post