Node.js y solicitudes intensivas de CPU
Comencé a jugar con el servidor HTTP Node.js y realmente me gusta escribir Javascript en el lado del servidor, pero algo me impide comenzar a usar Node.js para mi aplicación web.
Entiendo todo el concepto de E/S asíncrona, pero estoy algo preocupado por los casos extremos en los que el código de procedimiento consume mucha CPU, como la manipulación de imágenes o la clasificación de grandes conjuntos de datos.
Según tengo entendido, el servidor será muy rápido para solicitudes simples de páginas web, como ver una lista de usuarios o ver una publicación de blog. Sin embargo, si quiero escribir código con un uso intensivo de CPU (en el back-end de administración, por ejemplo) que genere gráficos o cambie el tamaño de miles de imágenes, la solicitud será muy lenta (unos pocos segundos). Dado que este código no es asíncrono, todas las solicitudes que lleguen al servidor durante esos pocos segundos se bloquearán hasta que finalice mi solicitud lenta.
Una sugerencia fue utilizar Web Workers para tareas intensivas de CPU. Sin embargo, me temo que los trabajadores web dificultarán la escritura de código limpio, ya que funciona incluyendo un archivo JS separado. ¿Qué pasa si el código intensivo de la CPU se encuentra en el método de un objeto? Es una mierda escribir un archivo JS para cada método que requiere un uso intensivo de la CPU.
Otra sugerencia fue generar un proceso hijo, pero eso hace que el código sea aún menos mantenible.
¿Alguna sugerencia para superar este obstáculo (percibido)? ¿Cómo se escribe código limpio orientado a objetos con Node.js y al mismo tiempo se garantiza que las tareas pesadas de la CPU se ejecuten de forma asíncrona?
Esto es un malentendido de la definición de servidor web: sólo debe usarse para "hablar" con los clientes. Las tareas pesadas deben delegarse a programas independientes (que por supuesto también pueden escribirse en JS).
Probablemente diría que está sucio, pero le aseguro que un proceso de servidor web atascado al cambiar el tamaño de las imágenes es simplemente peor (incluso para, digamos, Apache, cuando no bloquea otras consultas). Aun así, puedes utilizar una biblioteca común para evitar la redundancia de código.
EDITAR: Se me ocurrió una analogía; La aplicación web debe ser como un restaurante. Tienes camareros (servidor web) y cocineros (trabajadores). Los camareros están en contacto con los clientes y realizan tareas sencillas como ofrecer el menú o explicar si algún plato es vegetariano. Por otro lado, delegan tareas más duras en la cocina. Como los camareros sólo hacen cosas sencillas, responden rápidamente y los cocineros pueden concentrarse en su trabajo.
Node.js aquí sería un camarero único pero muy talentoso que puede procesar muchas solicitudes a la vez, y Apache sería un grupo de camareros tontos que solo procesan una solicitud cada uno. Si este camarero de Node.js comenzara a cocinar, sería una catástrofe inmediata. Aún así, cocinar también podría agotar incluso una gran cantidad de camareros apaches, sin mencionar el caos en la cocina y la progresiva disminución de la responsabilidad.
¡Lo que necesitas es una cola de tareas! Sacar las tareas de larga duración del servidor web es algo BUENO. Mantener cada tarea en un archivo js "separado" promueve la modularidad y la reutilización del código. Le obliga a pensar en cómo estructurar su programa de manera que sea más fácil de depurar y mantener a largo plazo. Otro beneficio de una cola de tareas es que los trabajadores pueden escribirse en un idioma diferente. Simplemente haga una tarea, haga el trabajo y escriba la respuesta.
algo como esto https://github.com/resque/resque
Aquí hay un artículo de github sobre por qué lo construyeron http://github.com/blog/542-introtaining-resque