Procesos en segundo plano en Node.js

96

¿Cuál es un buen enfoque para manejar procesos en segundo plano en una aplicación NodeJS?

Escenario : después de que un usuario publica algo en una aplicación, quiero procesar los datos, solicitar datos adicionales de recursos externos, etc. Todo esto lleva bastante tiempo, por lo que quiero que salga del bucle req / res. Lo ideal sería tener una cola de trabajos en la que pueda volcar rápidamente un trabajo y un demonio o un ejecutor de tareas siempre tomará el más antiguo y lo procesará.

En RoR lo hubiera hecho con algo como Trabajo retrasado. ¿Cuál es el equivalente de nodo de esta API?

Ole Spaarmann
fuente
4
La pregunta es una recomendación de software como está redactada ahora, que terminará cerrándose. Si tuviera que reemplazar la última oración con "¿Cuál es el equivalente NodeJS de esta API?" se vuelve más sobre el tema. Me gustaría ver esto respondido en lugar de cerrado, ya que necesito hacer algo similar.
ssube
Gracias, reformulé.
Ole Spaarmann
2
Buenas sugerencias a continuación. También está la ChildProcessAPI que puede ser útil. nodejs.org/api/child_process.html
lispHK01
stackoverflow.com/users/69349/ole-spaarmann - Me interesaría saber qué eligió finalmente y si pudiera proporcionar un ejemplo muy simple de cómo integró su decisión con NodeJS - ¡gracias!
MLissCetrus
@MLissCetrus Elegí aprender Elixir y no usar más NodeJS :)
Ole Spaarmann

Respuestas:

114

Si quieres algo ligero, que se ejecute en el mismo proceso que el servidor, te recomiendo encarecidamente Bull . Tiene una API simple que permite un control detallado sobre sus colas.

Si está buscando algo que se ejecute como un proceso de trabajo independiente, quizás busque en Kue . Puede ejecutarse como un servidor de API RESTful e incluso tiene varias aplicaciones de front-end escritas para él.

Si está familiarizado con Ruby's Resque, hay una implementación de nodo llamada Node-resque

Bull, Kue y Node-resque están respaldados por Redis , que es omnipresente entre las colas de trabajadores de Node.js. Los 3 podrían hacer lo que hace DelayedJob de RoR, se trata de las características específicas que desea y sus preferencias de API.

Yuri Zarubin
fuente
3
Esta es una muy buena respuesta, pero mencionar la API ChildProcess y el módulo webworker-threads podría hacerlo genial. ;)
ssube
@ssube No estoy de acuerdo contigo. A menos que te refieras a crear una bifurcación que mira una cola para ejecutar algún comando, tienes razón. +1 de mi parte. Child_process es lo que estoy usando y mi problema es que podría abrir un gran conjunto de procesos, pero si tuviera una forma de administrar las tareas que se ejecutarán en una cola, entonces estaría feliz de que CP sea una buena solución. Esto se puede hacer, pero el punto es no hacer todo el trabajo usted mismo, sino reutilizar el código que está probado en batalla (en este caso, algo como Kue que hace toda la magia que necesita y permite integraciones de API).
dewwwald
¿Bull funciona con la agrupación en clústeres de PM2? ¿O necesita crear sus propios clústeres manualmente, como se muestra en su documentación?
Shayan Nahrvar
31

Los trabajos en segundo plano no están directamente relacionados con el trabajo de su servicio web, por lo que no deberían estar en el mismo proceso. A medida que aumenta la escala, el uso de memoria de los trabajos en segundo plano afectará el rendimiento del servicio web. Pero puede ponerlos en el mismo repositorio de código si lo desea, lo que tenga más sentido.

Una buena opción para la mensajería entre los dos procesos sería redis , si soltar un mensaje de vez en cuando está bien. Si desea que "no se deje ningún mensaje", necesitará un corredor más pesado como Rabbit . Su proceso de servicio web puede publicar y su proceso de trabajo en segundo plano puede suscribirse.

No es necesario que los dos procesos estén cohospedados, pueden estar en máquinas virtuales separadas, contenedores Docker, lo que sea que use. Esto le permite escalar horizontalmente sin muchos problemas.

wberry
fuente
3
¿Realmente la única respuesta que ha mencionado a Conejo? Esta es la respuesta empresarial. +1
Augie Gardner
11

Si está utilizando MongoDB, le recomiendo Agenda . De esa manera, las instancias de Redis separadas no se están ejecutando y las características como la programación, las colas y la interfaz de usuario web están presentes. La interfaz de usuario de la agenda es opcional y, por supuesto, se puede ejecutar por separado.

También recomendaría configurar una abstracción débilmente acoplada entre la lógica de la aplicación y el sistema de cola / programación para que todo el sistema de procesamiento en segundo plano pueda intercambiarse si es necesario. En otras palabras, mantenga la mayor parte de la lógica de aplicación / procesamiento alejada de las definiciones de trabajo de su Agenda para mantenerlas livianas.

sean2078
fuente
3

Me gustaría sugerir el uso de Redis. para programar trabajos. Tiene muchas estructuras de datos diferentes, siempre puede elegir una que se adapte mejor a su caso de uso.

Mencionaste RoR y DJ, así que supongo que estás familiarizado con sidekiq. Puede usar node-sidekiq para la programación de trabajos si lo desea, pero es subóptimo en mi opinión, ya que su propósito principal es integrar nodejs con RoR.

Para demonizar a los trabajadores, recomendaría usar PM2 . Es ampliamente utilizado y mantenido activamente. Resuelve muchos problemas (por ejemplo, implementación, monitoreo, agrupación en clústeres), así que asegúrese de que no sea una exageración para usted.

Stefkin
fuente
1

Probé bee-queue & bull y elegí bull al final. Primero elegí bee-queue porque es bastante simple, sus ejemplos son fáciles de entender, mientras que los ejemplos de Bull son un poco complicados. Bee's wiki Bee Queue's Origin también me resuena. Pero el problema con bee es <1> su tiempo de resolución de problemas es bastante lento, su última actualización fue hace 10 meses. <2> No encuentro una manera fácil de pausar / cancelar el trabajo.

Bull, por otro lado, actualiza con frecuencia sus códigos, en respuesta a los problemas. La evaluación de la cola de trabajos de Node.js dijo que la debilidad de Bull es el "tiempo de resolución de problemas lento", ¡pero mi experiencia es lo contrario!

Pero de todos modos su API es similar, por lo que es bastante fácil cambiar de una a otra.

Qiulang
fuente
-6

Sugiero usar un marco Node.js adecuado para crear su aplicación.

Creo que el más poderoso y fácil de usar es Sails.js .

Es un marco MVC, por lo que si está acostumbrado a desarrollar en ROR, ¡lo encontrará muy, muy fácil!

Si lo usa, ya presenta un poderoso administrador de trabajos (en términos de javascript).

new sails.cronJobs('0 01 01 * * 0', function () {
   sails.log.warn("START ListJob");
}, null, true, "Europe/Dublin");

Si necesitas más información no dudes en contactarme!

Zio Mak Sò
fuente
5
Estoy buscando un administrador de procesos en segundo plano para Node. Por definición, esto debería estar separado de su aplicación web. Y no debería importar si usa Sails, Express, Hapi o lo que quiera.
Ole Spaarmann
Ok, puedes probar Bull o Webworker-Threads ... buena suerte con Node.js :)
Zio Mak Sò
Parece que sails.js es bastante grande y hace mucho más que cronJobs. Encontré node-cron ( github.com/kelektiv/node-cron ) que apuesto a que es lo que usa sails.js.
pbatey