nodejs javascript node.js heroku scalability

javascript - nodejs - heroku dashboard login



Arquitectura de aplicaciĆ³n escalable Node.js (1)

En el pasado, jugaba con Node.js solo en mi máquina local, así que solo tengo experiencia con aplicaciones de proceso único de Node.js. Ahora me gustaría crear una aplicación web que podría publicar en la web.

Esta aplicación web sería algo así como un juego multijugador: usar Socket.IO para la comunicación cliente-servidor, Express para el manejo de solicitudes HTTP, grunt para la administración de tareas, etc. Me gustaría usar otros paquetes NPM también para diversas tareas.

Me gustaría diseñar la arquitectura de esta aplicación para

  • habilitar la escalabilidad horizontal (más adelante, cuando tengo muchos visitantes, no tengo que volver a escribir toda la aplicación)
  • minimizar las dependencias en diferentes entornos de ejecución (para maximizar la portabilidad)

¿Cómo puedo lograr esto usando Nodo?

Supongo que la arquitectura de alto nivel consistiría en:

  • Diferentes procesos de servidor (cada proceso ejecutaría una instancia de Express y manejaría las solicitudes HTTP entrantes).
  • Debe haber un equilibrador de carga en alguna parte.
  • Opcionalmente: procesos en segundo plano que podrían ejecutarse periódicamente y procesar los "datos compartidos"

Dado que mi aplicación sería una aplicación multijugador donde cada usuario podría interactuar con los otros usuarios en línea, debería almacenar algún estado común ("datos compartidos") en algún lugar que pueda compartirse entre esos procesos.

Para mantener las cosas simples, al principio no tengo que conservar estos datos compartidos, por lo que creo que debería usar un almacén de datos en memoria como Redis.

El panorama general se vería así:

Este diseño plantea algunas preguntas:

¿Cómo engendrar los procesos?

¿Debo usar Node''s child_process o los módulos de cluster y comenzar los procesos de trabajo manualmente? Por cierto, ¿es posible iniciarlos manualmente, por ejemplo, si implemento mi aplicación en Heroku o Nodejitsu ?

O: is there a better way to store these information in a config file?

Quiero decir, sería mejor si pudiera configurar cuántas instancias de servidor quiero no con la edición del código sino con una entrada de configuración.

Los límites del sistema?

Si engendro los procesos manualmente, entonces (supongo) todos los procesos se ejecutarán en el mismo servidor (virtual).

Si este servidor tiene, digamos 4 núcleos de CPU, entonces puede generar 4 instancias de Nodo como máximo, porque si genera más, su CPU hará cambios de contexto que arruinarían el rendimiento general.

¿Qué debo hacer si necesito más instancias de proceso? Digamos que necesito 100 instancias de servidor. ¿Tengo que implementar mi aplicación en 25 servidores y generar 4 procesos en cada servidor?

Me parece que los servicios de alojamiento como Nodejitsu de alguna manera te ocultan esta capa de límite del sistema, pero no veo cómo funciona en la práctica.

Especialmente que existe este componente proveedor de "datos compartidos". Supongo que este proveedor (como un servidor Redis) tiene que ejecutarse en un servidor diferente para que esté disponible para todos los procesos. Pero en este caso, podría convertirse fácilmente en un cuello de botella, ¿no es así?

Equilibrador de carga?

Si uso algún servicio de alojamiento, ¿tengo que configurar yo mismo la capa del equilibrador de carga?

Editar:

Para responder algunas preguntas prácticas: en el primer paso, quiero manejar 4-500 usuarios concurrentes (conexiones Socket.IO) sin problemas. Esta es una cantidad de visitantes que puedo alcanzar de manera realista.

Pero tengo curiosidad de que sea posible (y si es así, ¿cómo?) Diseñar una arquitectura de aplicación que pueda ser fácilmente escalable. Digamos que mi sitio web se volverá popular de un día para otro y, en lugar de tratar con unos cientos de usuarios concurrentes, al día siguiente tendré que atender a algunos miles.

Por lo que sé, los servicios de alojamiento en la nube como Heroku y Nodejitsu podrían adaptarse fácilmente a estos escenarios (solo tiene que aumentar el número de trabajadores / dynos / lo que sea), pero solo funciona si tiene la arquitectura de aplicación correcta.

Respecto a los datos compartidos: no quiero persistirlos. Solo quiero mantenerlo en la memoria. Se necesita algún proveedor de datos compartidos por un lado debido a Socket.IO: un usuario podría enviar un mensaje a un usuario que se encuentra en otro "nodo". Para esto usaría a Redis como un proveedor de datos compartidos. El número de transacciones que Redis necesita manejar es igual a la cantidad de mensajes enviados / recibidos con Socket.IO, ~ 1000-1500 mensajes / seg.

Por otro lado, se necesita algún proveedor de datos compartidos porque quiero conectar a los usuarios según varios criterios. Más adelante, los procesos en segundo plano recalcularán / refinarán periódicamente la probabilidad (el "peso") de esas conexiones. Ya tengo una idea de cómo implementar una estructura de datos eficiente para manejar inserciones / eliminaciones rápidas en esta tabla en memoria. Por lo tanto, el componente "proveedor de datos compartidos" consistiría en algún código del lado del servidor (tal vez Node.js) que podría almacenar estas conexiones.

Sé que es TL; DR, pero espero que responda a todas sus preguntas técnicas sobre el problema. :)


Está bien, esto es mucho por lo que pasar. Primero, su separación de preocupaciones es apropiada, necesitará una forma de comunicación para los procesos, esto puede ser a través de una instancia de Redis, u otro sistema de pub / sub o req / res (ya sea redis, kue, zmq, etc.). NOTA: es probable que aún deba desechar su uso de datos / mensajes si crece significativamente, al menos tanto como sea posible. Puede aliviar esto si usa un sistema de cola de mensajes más complejo (Rabbit u otro AMQP).

Parece que su principal preocupación es la gestión de procesos. En general, si está utilizando Heroku, debería poder escalar un solo proceso por nodo, pero luego necesitará que su (s) nodo (s) coordinador (es) estén fuera. Si usted es auto-hospedante (no a través de heroku o similar), entonces debería buscar en pm2 o forever ... Luego puede abrir varias instancias ...

En su mayor parte, sus problemas de logística / infraestructura variarán según sus necesidades. Sin mencionar las estrategias más nuevas que involucran CI / CD, docker y otras. O su uso de base de datos.