Pregunta

He empezado a juguetear con Node.js servidor HTTP y realmente como para el lado del servidor de escritura Javascript pero algo me está guardando de lanzarte en Node.js para mi aplicación web.

Me entender todo el concepto asíncrono de E / S pero me preocupa un poco acerca de los casos extremos donde el código de procedimiento es muy intensivo de la CPU como la manipulación de imágenes o la clasificación de grandes conjuntos de datos.

A mi entender, el servidor va a ser muy rápido para las solicitudes de páginas web sencillas, tales como la visualización de una lista de usuarios o la visualización de una entrada de blog. Sin embargo, si quiero escribir código muy intensiva de CPU (en la parte de atrás de administración, por ejemplo) que genera gráficos o cambia el tamaño de miles de imágenes, la solicitud será muy lento (unos pocos segundos). Dado que este código no es asíncrona, cada solicitudes que llegan al servidor durante esos pocos segundos se bloquearán hasta que mi solicitud se hace lenta.

Una sugerencia era utilizar Web Workers para las tareas intensivas de la CPU. Sin embargo, estoy trabajadores web tenga miedo a hacer que sea difícil escribir código limpio ya que funciona mediante la inclusión de un archivo JS separada. ¿Qué pasa si el código intensivo de la CPU se encuentra en el método de un objeto? En cierto modo se aspira a escribir un archivo JS para cada método que es la CPU.

Otra sugerencia fue la de generar un proceso hijo, sino que hace que el código aún menos mantenible.

¿Alguna sugerencia para superar este obstáculo (percibida)? ¿Cómo se escribe código orientado a objetos limpios con Node.js al hacer tareas pesadas de la CPU seguro que son ejecutados asíncrono?

¿Fue útil?

Solución

Lo que necesita es una cola de tareas! Mover las tareas a largo corriendo del servidor web es una buena cosa. Mantener cada tarea en el archivo js "separados" promueve la modularidad y la reutilización de código. Te obliga a pensar en la forma de estructurar el programa de una manera que hará que sea más fácil de depurar y mantener en el largo plazo. Otro de los beneficios de una cola de tareas es que los trabajadores pueden estar escritos en un lenguaje diferente. Basta con meter una tarea, hacer el trabajo, y escribir la parte posterior respuesta.

https://github.com/resque/resque

Aquí está un artículo de github acerca de por qué la construyeron http://github.com/blog / 542-introducir-resque

Otros consejos

Esto es mala interpretación de la definición de servidor web - que sólo se debe utilizar para "hablar" con los clientes. tareas de carga pesada deben ser delegadas a programas independientes (que por supuesto puede ser también escrito en JS).
Probablemente diría que es sucio, pero le aseguro que un proceso de servidor web atrapado en cambiar el tamaño de las imágenes es peor (incluso para digamos Apache, cuando no bloquea otras consultas). Aún así, es posible utilizar una biblioteca común para evitar la redundancia de código.

EDIT: Me han llegado con una analogía; aplicación web debe ser como un restaurante. Tiene camareros (servidor web) y cocineros (trabajadores). Los camareros están en contacto con los clientes y realizar tareas sencillas como proporcionar menú o explicar si algún plato es vegetariano. Por otro lado delegan las tareas más difíciles de la cocina. Debido a que los camareros están haciendo sólo cosas simples que responden rápida y cocineros pueden concentrarse en su trabajo.

Node.js aquí sería un único pero muy talentoso camarero que puede procesar muchos pedidos a la vez, y Apache sería una banda de montaplatos que acaba de procesar uno Pedir a cada una. Si ésta Node.js camarero comenzaría a cocinar, sería una catástrofe inmediata. Aún así, la cocina también podría agotar incluso una gran cantidad de camareros Apache, sin mencionar el caos en la cocina y la disminución progresiva de responsitivity.

Usted no quiere que su CPU para ejecutar código intensiva asíncrono, que desea que se ejecute en paralelo . Es necesario para conseguir el trabajo de procesamiento de la rosca que está sirviendo peticiones HTTP. Es la única manera de resolver este problema. Con NodeJS la respuesta es la racimo módulo de , para el desove procesos hijo a hacer el trabajo pesado. (Que yo sepa nodo no tiene ningún concepto de hilos / memoria compartida, es procesos o nada). Usted tiene dos opciones para la forma de estructurar su aplicación. Usted puede obtener la solución 80/20 en desove 8 servidores HTTP y manejo de las tareas de cálculo intensivo de forma sincrónica en los procesos hijos. Hacer eso es bastante simple. Se podría tomar una hora para leer sobre él en ese enlace. De hecho, si sólo fuera rasgar el código de ejemplo en la parte superior de ese vínculo que se conseguirá el 95% del camino.

La otra manera de estructurar esta es la creación de una cola de trabajos y enviar grandes tareas de computación a través de la cola. Tenga en cuenta que hay una gran cantidad de gastos generales asociados con el IPC para una cola de trabajos, por lo que esto sólo es útil cuando las tareas son apreciablemente más grande que el de arriba.

Me sorprende que ninguna de estas otras respuestas, incluso mención clúster.

Antecedentes: código asíncrono es el código que se suspende hasta que suceda algo en otro lugar , momento en el que el código se despierta y continúa la ejecución. Un caso muy común en la que algo lenta debe suceder en otro lugar es de E / S.

código asíncrono no es útil si se trata de su procesador que se encarga de hacer el trabajo. Esto es precisamente el caso de las tareas de cálculo intensivo "".

Ahora, podría parecer que es un código asíncrono nicho, pero en realidad es muy común. Lo que ocurre no ser útil para tareas intensivas de cálculo.

en espera de E / S es un patrón que siempre sucede en los servidores web, por ejemplo. Cada cliente que se conecta a su Sever consigue un zócalo. La mayoría de las veces las tomas están vacías. Usted no quiere hacer nada hasta que recibe una toma algunos datos, momento en el que desea manejar la petición. Bajo el capó de un servidor HTTP como nodo está utilizando una biblioteca de concurso completo (libev) para realizar un seguimiento de los miles de sockets abiertos. Los notifica OS libev, y luego notifica a libev NodeJS cuando una de las tomas obtiene los datos, y luego nodejs pone un evento en la cola de eventos, y sus patadas código HTTP en este punto y controla los eventos uno tras otro. Eventos no consiguen poner en la cola hasta que el conector tiene algunos datos, por lo que nunca se esperan eventos en los datos -. Ya está ahí para ellos

Individual roscada servidores web basados ??en eventos tiene sentido como un paradigma cuando el cuello de botella está esperando en un montón de conexiones de socket su mayoría vacías y que no quiere un hilo entero o proceso para cada conexión inactiva y no quieren sondear sus 250k enchufes para encontrar la siguiente que tiene datos en él.

Un par de enfoques que puede utilizar.

Como notas @Tim, puede crear una tarea asíncrona que se encuentra al aire libre o en paralelo a su lógica principal de la porción. Depende de sus requisitos exactos, pero incluso cron puede actuar como un mecanismo de cola.

WebWorkers puede trabajar para sus procesos asincrónicos, pero que actualmente no están soportadas por node.js. Hay un par de extensiones que proporcionan apoyo, por ejemplo: http://github.com/cramforce/node -worker

Aunque aún así puedes módulos siguen la reutilización y el código a través de la norma "requiere" mecanismo. Sólo tiene que asegurarse de que el envío inicial para el trabajador pasa toda la información necesaria para procesar los resultados.

Uso child_process es una solución. Pero cada proceso secundarias generadas pueden consumir una gran cantidad de memoria en comparación con Go goroutines

También puede utilizar una solución basada en colas como Kue

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top