Processi in background in Node.js


96

Qual è un buon approccio per gestire i processi in background in un'applicazione NodeJS?

Scenario : dopo che un utente ha pubblicato qualcosa in un'app, desidero analizzare i dati, richiedere dati aggiuntivi da risorse esterne, ecc. Tutto questo richiede molto tempo, quindi lo voglio fuori dal ciclo req / res. L'ideale sarebbe avere solo una coda di lavori in cui è possibile eseguire rapidamente il dump di un lavoro e un daemon o un task runner prenderà sempre quello più vecchio e lo elaborerà.

In RoR l'avrei fatto con qualcosa come Delayed Job. Qual è l'equivalente Node di questa API?


4
La domanda è una raccomandazione del software come è formulata ora, che finirà per essere chiusa. Se dovessi sostituire l'ultima frase con "Qual è l'equivalente NodeJS di questa API?" diventa più in tema. Mi piacerebbe vedere questa risposta piuttosto che chiusa, poiché ho bisogno di fare qualcosa di simile.
ssube

Grazie, riformulato.
Ole Spaarmann

2
Buoni suggerimenti di seguito. C'è anche l' ChildProcessAPI che potrebbe essere utile. nodejs.org/api/child_process.html
lispHK01

stackoverflow.com/users/69349/ole-spaarmann - Sarei interessato a sapere cosa hai finalmente scelto e se potessi fornire un esempio molto semplice di come hai integrato la tua decisione con NodeJS - grazie!
MLissCetrus

@MLissCetrus Ho scelto di imparare l'elisir e non usare più NodeJS :)
Ole Spaarmann

Risposte:


114

Se vuoi qualcosa di leggero, che funzioni nello stesso processo del server, consiglio vivamente Bull . Ha una semplice API che consente un controllo granulare delle tue code.

Se stai cercando qualcosa che funzioni come un processo di lavoro autonomo, forse esamina Kue . Può funzionare come un server API RESTful e ha anche diverse app front-end scritte per esso.

Se hai familiarità con Ruby's Resque, esiste un'implementazione del nodo chiamata Node-resque

Bull, Kue e Node-resque sono tutti supportati da Redis , che è onnipresente tra le code dei lavoratori di Node.js. Tutti e 3 sarebbero in grado di fare ciò che fa RoR's DelayedJob, dipende dalle funzionalità specifiche che desideri e dalle tue preferenze API.


3
Questa è un'ottima risposta, ma menzionare l'API ChildProcess e il modulo thread webworker potrebbe renderlo eccezionale. ;)
ssube

@ssube Non sono d'accordo con te. A meno che tu non intenda creare un fork che guarda una coda per eseguire qualche comando, hai ragione. +1 da me. Child_process è quello che sto usando e il mio problema è che potrei aprire un enorme set di processi, ma se avessi un modo per gestire le attività da eseguire in una coda, allora sarei felice che CP sia una buona soluzione. Questo può essere fatto, ma il punto è non fare tutto il lavoro da soli, ma riutilizzare il codice testato in battaglia (in questo caso qualcosa come Kue che fa tutta la magia di cui hai bisogno e consente le integrazioni api).
dewwwald

Bull funziona con il clustering PM2? O hai bisogno di creare manualmente i tuoi cluster, come mostrato nella loro documentazione?
Shayan Nahrvar

31

I lavori in background non sono direttamente correlati al lavoro del tuo servizio web, quindi non dovrebbero essere nello stesso processo. Man mano che si aumenta, l'utilizzo della memoria dei processi in background influirà sulle prestazioni del servizio Web. Ma puoi metterli nello stesso repository di codice se vuoi, qualunque cosa abbia più senso.

Una buona scelta per la messaggistica tra i due processi sarebbe redis , se inviare un messaggio ogni tanto è OK. Se vuoi "nessun messaggio lasciato indietro" avrai bisogno di un broker più pesante come Rabbit . Il processo del servizio Web può essere pubblicato e il processo del lavoro in background può iscriversi.

Non è necessario che i due processi siano co-ospitati, possono trovarsi su VM separate, contenitori Docker, qualunque cosa tu usi. Questo ti consente di scalare senza troppi problemi.


3
Davvero l'unica risposta che ha menzionato Rabbit? Questa è la risposta aziendale. +1
Augie Gardner

11

Se stai usando MongoDB, ti consiglio Agenda . In questo modo, le istanze Redis separate non vengono eseguite e sono presenti funzionalità come la pianificazione, l'accodamento e l'interfaccia utente Web. L'interfaccia utente dell'agenda è facoltativa e può essere eseguita separatamente, ovviamente.

Consiglierei anche di impostare un'astrazione debolmente accoppiata tra la logica dell'applicazione e il sistema di accodamento / pianificazione in modo che l'intero sistema di elaborazione in background possa essere sostituito se necessario. In altre parole, mantieni la logica di applicazione / elaborazione lontana dalle definizioni di lavoro dell'Agenda per mantenerle leggere.


3

Vorrei suggerire di utilizzare Redis per la pianificazione dei lavori. Ha molte strutture di dati diverse, puoi sempre sceglierne una che si adatta meglio al tuo caso d'uso.

Hai menzionato RoR e DJ, quindi presumo tu abbia familiarità con sidekiq. Puoi usare node-sidekiq per la pianificazione dei lavori se lo desideri, ma non è ottimale, poiché il suo scopo principale è integrare nodejs con RoR.

Per la demonizzazione dei lavoratori consiglierei di utilizzare PM2 . È ampiamente utilizzato e mantenuto attivamente. Risolve molti problemi (es. Distribuzione, monitoraggio, clustering), quindi assicurati che non sia eccessivo per te.


1

Ho provato la coda delle api e il toro e alla fine ho scelto il toro. Per prima cosa ho scelto la coda d'api b / c è abbastanza semplice, i loro esempi sono facili da capire, mentre gli esempi di tori sono un po 'complicati. Il wiki di ape Bee Queue's Origin risuona anche con me. Ma il problema con bee è <1> che il tempo di risoluzione dei problemi è piuttosto lento, l'ultimo aggiornamento è stato di 10 mesi fa. <2> Non riesco a trovare un modo semplice per mettere in pausa / annullare il lavoro.

Bull, d'altra parte, aggiorna frequentemente i propri codici, in risposta ai problemi. La valutazione della coda di lavoro di Node.js ha affermato che la debolezza del toro è "il tempo di risoluzione dei problemi lento", ma la mia esperienza è l'opposto!

Ma comunque la loro api è simile quindi è abbastanza facile passare da una all'altra.


-6

Suggerisco di utilizzare un framework Node.js appropriato per creare la tua app.

Penso che il più potente e facile da usare sia Sails.js .

È un framework MVC quindi se sei abituato a sviluppare in ROR, lo troverai molto molto facile!

Se lo usi, è già presente un potente (in termini javascript) gestore dei lavori.

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

Se hai bisogno di maggiori informazioni non esitare a contattarmi!


5
Sto cercando un gestore di processi in background per Node. Per definizione questo dovrebbe essere separato dalla tua app web. E non dovrebbe importare se usi Sails, Express, Hapi o quello che preferisci.
Ole Spaarmann

Ok puoi provare Bull o Webworker-Threads ... buona fortuna con Node.js :)
Zio Mak Sò

Sembra che sails.js sia piuttosto grande e faccia molto di più che cronJobs. Ho trovato node-cron ( github.com/kelektiv/node-cron ) che scommetto è quello che usa sails.js.
pbatey
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.