Processus d'arrière-plan dans Node.js

96

Quelle est la bonne approche pour gérer les processus d'arrière-plan dans une application NodeJS?

Scénario : après qu'un utilisateur a publié quelque chose sur une application, je veux analyser les données, demander des données supplémentaires à des ressources externes, etc. Tout cela prend beaucoup de temps, donc je veux qu'il soit hors de la boucle req / res. L'idéal serait d'avoir simplement une file d'attente de travaux sur laquelle vous pouvez vider rapidement un travail et un démon ou un exécuteur de tâches prendra toujours le plus ancien et le traitera.

Dans RoR, je l'aurais fait avec quelque chose comme Delayed Job. Quel est l'équivalent Node de cette API?

Ole Spaarmann
la source
4
La question est une recommandation logicielle telle qu'elle est formulée maintenant, qui finira par se fermer. Si vous deviez remplacer la dernière phrase par "Quel est l'équivalent NodeJS de cette API?" cela devient plus sur le sujet. J'aimerais voir cela répondu plutôt que fermé, car je dois faire quelque chose de similaire.
ssube
Merci, reformulé.
Ole Spaarmann
2
Bonnes suggestions ci-dessous. Il y a aussi l' ChildProcessAPI qui pourrait être utile. nodejs.org/api/child_process.html
lispHK01
stackoverflow.com/users/69349/ole-spaarmann - Je serais intéressé de savoir ce que vous avez finalement choisi et si vous pouviez fournir un exemple très simple de la façon dont vous avez intégré votre décision avec NodeJS - merci!
MLissCetrus
@MLissCetrus J'ai choisi d'apprendre Elixir et de ne plus utiliser NodeJS :)
Ole Spaarmann

Réponses:

114

Si vous voulez quelque chose de léger, qui fonctionne dans le même processus que le serveur, je recommande fortement Bull . Il dispose d'une API simple qui permet un contrôle fin sur vos files d'attente.

Si vous recherchez quelque chose qui fonctionne en tant que processus de travail autonome, consultez peut-être Kue . Il peut fonctionner en tant que serveur API RESTful et a même plusieurs applications frontales écrites pour lui.

Si vous connaissez Ruby's Resque, il existe une implémentation de nœud appelée Node-resque

Bull, Kue et Node-resque sont tous soutenus par Redis , qui est omniprésent parmi les files d'attente de travail Node.js. Tous les 3 seraient capables de faire ce que fait DelayedJob de RoR, il s'agit de fonctionnalités spécifiques que vous souhaitez et de vos préférences API.

Yuri Zarubin
la source
3
C'est une très bonne réponse, mais mentionner l'API ChildProcess et le module Webworker -threads pourrait la rendre géniale. ;)
ssube
@ssube Je ne suis pas d'accord avec vous. Sauf si vous voulez dire créer un fork qui regarde une file d'attente pour exécuter une commande, vous avez raison. +1 de moi. Child_process est ce que j'utilise et mon problème est que je pourrais ouvrir un vaste ensemble de processus, mais si j'avais un moyen de gérer les tâches à exécuter dans une file d'attente, je serais heureux que CP soit une bonne solution. Cela peut être fait, mais le but n'est pas de faire tout le travail vous-même, mais de réutiliser du code qui a été testé au combat (dans ce cas, quelque chose comme Kue qui fait toute la magie dont vous avez besoin et autorise les intégrations d'API).
dewwwald
Bull fonctionne-t-il avec le clustering PM2? Ou avez-vous besoin de créer vos propres clusters manuellement, comme indiqué dans leur documentation?
Shayan Nahrvar
31

Les travaux d'arrière-plan ne sont pas directement liés à votre travail de service Web, ils ne doivent donc pas être dans le même processus. Au fur et à mesure que vous augmentez, l'utilisation de la mémoire des travaux d'arrière-plan aura un impact sur les performances du service Web. Mais vous pouvez les mettre dans le même référentiel de code si vous le souhaitez, ce qui a le plus de sens.

Un bon choix pour la messagerie entre les deux processus serait redis , si laisser tomber un message de temps en temps est OK. Si vous voulez "aucun message laissé pour compte", vous aurez besoin d'un courtier plus lourd comme Rabbit . Votre processus de service Web peut publier et votre processus de travail en arrière-plan peut s'abonner.

Il n'est pas nécessaire que les deux processus soient co-hébergés, ils peuvent être sur des machines virtuelles distinctes, des conteneurs Docker, quoi que vous utilisiez. Cela vous permet d'évoluer sans trop de problèmes.

wberry
la source
3
Vraiment la seule réponse qui a mentionné Rabbit? C'est la réponse de l'entreprise. +1
Augie Gardner
11

Si vous utilisez MongoDB, je recommande Agenda . De cette façon, des instances Redis distinctes ne sont pas en cours d'exécution et des fonctionnalités telles que la planification, la mise en file d'attente et l'interface utilisateur Web sont toutes présentes. L'interface utilisateur de l'agenda est facultative et peut être exécutée séparément, bien sûr.

Je recommande également de configurer une abstraction faiblement couplée entre la logique de votre application et le système de mise en file d'attente / de planification afin que l'ensemble du système de traitement en arrière-plan puisse être remplacé si nécessaire. En d'autres termes, gardez autant de logique d'application / de traitement loin de vos définitions de travail Agenda afin de les garder légères.

sean2078
la source
3

Je voudrais suggérer d'utiliser Redis pour planifier des tâches. Il a beaucoup de structures de données différentes, vous pouvez toujours en choisir une qui convient le mieux à votre cas d'utilisation.

Vous avez mentionné RoR et DJ, donc je suppose que vous connaissez sidekiq. Vous pouvez utiliser node-sidekiq pour la planification des travaux si vous le souhaitez, mais son imo sous-optimal, car son objectif principal est d'intégrer nodejs avec RoR.

Pour la démonisation des ouvriers, je recommande d'utiliser PM2 . Il est largement utilisé et activement maintenu. Cela résout beaucoup de problèmes (par exemple, le déploiement, la surveillance, la mise en cluster), alors assurez-vous que ce ne sera pas excessif pour vous.

stefkin
la source
1

J'ai essayé bee-queue & bull et j'ai finalement choisi bull. J'ai d'abord choisi bee-queue car c'est assez simple, leurs exemples sont faciles à comprendre, tandis que les exemples de taureaux sont un peu compliqués. bee's wiki L'origine de Bee Queue résonne également avec moi. Mais le problème avec bee est <1> que leur temps de résolution des problèmes est assez lent, leur dernière mise à jour remonte à 10 mois. <2> Je ne trouve pas de moyen simple de suspendre / annuler une tâche.

Bull, en revanche, met fréquemment à jour ses codes, en réponse aux problèmes. L'évaluation de la file d'attente de travaux de Node.js a déclaré que la faiblesse de Bull est "le temps de résolution des problèmes lent", mais mon expérience est le contraire!

Mais de toute façon, leur API est similaire, il est donc assez facile de passer de l'une à l'autre.

Qiulang
la source
-6

Je suggère d'utiliser un cadre Node.js approprié pour créer votre application.

Je pense que le plus puissant et le plus facile à utiliser est Sails.js .

C'est un framework MVC donc si vous avez l'habitude de développer en ROR, vous le trouverez très très facile!

Si vous l'utilisez, il présente déjà un gestionnaire de travaux puissant (en termes javascript).

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

Si vous avez besoin de plus d'informations, n'hésitez pas à me contacter!

Zio Mak Sò
la source
5
Je recherche un gestionnaire de processus d'arrière-plan pour Node. Par définition, cela doit être séparé de votre application Web. Et peu importe que vous utilisiez Sails, Express, Hapi ou ce que vous voulez.
Ole Spaarmann le
Ok, vous pouvez essayer Bull ou Webworker-Threads ... bonne chance avec Node.js :)
Zio Mak Sò
On dirait que sails.js est assez gros et fait bien plus que cronJobs. J'ai trouvé node-cron ( github.com/kelektiv/node-cron ) que je parie que c'est ce que sails.js utilise.
pbatey