Hintergrundprozesse in Node.js.

96

Was ist ein guter Ansatz, um Hintergrundprozesse in einer NodeJS-Anwendung zu handhaben?

Szenario : Nachdem ein Benutzer etwas in eine App gepostet hat, möchte ich die Daten verarbeiten, zusätzliche Daten von externen Ressourcen anfordern usw. All dies ist ziemlich zeitaufwändig, daher möchte ich, dass es aus der Req / Res-Schleife entfernt wird. Ideal wäre es, nur eine Warteschlange mit Jobs zu haben, in die Sie einen Job schnell kopieren können, und ein Daemon oder Task-Runner nimmt immer den ältesten und verarbeitet ihn.

In RoR hätte ich es mit so etwas wie Delayed Job gemacht. Was ist das Knotenäquivalent dieser API?

Ole Spaarmann
quelle
4
Die Frage ist eine Softwareempfehlung, wie sie jetzt formuliert ist, die am Ende geschlossen wird. Wenn Sie den letzten Satz durch "Was ist das NodeJS-Äquivalent dieser API?" Ersetzen würden. es wird mehr zum Thema. Ich würde es begrüßen, wenn dies beantwortet und nicht geschlossen würde, da ich etwas Ähnliches tun muss.
ssube
Danke, umformuliert.
Ole Spaarmann
2
Gute Vorschläge unten. Es gibt auch die ChildProcessAPI, die nützlich sein könnte. nodejs.org/api/child_process.html
lispHK01
stackoverflow.com/users/69349/ole-spaarmann - Ich würde mich interessieren, was Sie letztendlich ausgewählt haben und ob Sie ein sehr einfaches Beispiel dafür liefern könnten, wie Sie Ihre Entscheidung in NodeJS integriert haben - danke!
MLissCetrus
@MLissCetrus Ich habe mich entschieden, Elixier zu lernen und NodeJS nicht mehr zu verwenden :)
Ole Spaarmann

Antworten:

114

Wenn Sie etwas Leichtes wollen, das im selben Prozess wie der Server ausgeführt wird, empfehle ich dringend Bull . Es verfügt über eine einfache API, die eine differenzierte Kontrolle über Ihre Warteschlangen ermöglicht.

Wenn Sie nach etwas suchen, das als eigenständiger Arbeitsprozess ausgeführt wird, schauen Sie vielleicht nach Kue an . Es kann als RESTful-API-Server ausgeführt werden und hat sogar mehrere Front-End-Apps dafür geschrieben.

Wenn Sie mit Ruby's Resque vertraut sind, gibt es eine Knotenimplementierung namens Knotenimplementierung Node-Resque

Bull, Kue und Node-resque werden alle von Redis unterstützt , das in den Warteschlangen von Node.j allgegenwärtig ist. Alle 3 könnten das tun, was DelayedJob von RoR tut, es kommt auf bestimmte Funktionen an, die Sie möchten, und auf Ihre API-Einstellungen.

Yuri Zarubin
quelle
3
Dies ist eine sehr gute Antwort, aber die Erwähnung der ChildProcess-API und des Webworker-Threads- Moduls könnte es großartig machen. ;)
ssube
@ssube Ich bin nicht einverstanden mit dir. Wenn Sie nicht meinen, eine Verzweigung zu erstellen, die eine Warteschlange zum Ausführen eines Befehls betrachtet, haben Sie Recht. +1 von mir. Child_process verwende ich und mein Problem ist, dass ich eine Vielzahl von Prozessen eröffnen könnte. Wenn ich jedoch die Aufgaben verwalten könnte, die in einer Warteschlange ausgeführt werden sollen, wäre ich froh, dass CP eine gute Lösung ist. Dies kann getan werden, aber es geht nicht darum, die ganze Arbeit selbst zu erledigen, sondern den kampferprobten Code wiederzuverwenden (in diesem Fall so etwas wie Kue, das die gesamte Magie ausführt, die Sie benötigen, und API-Integrationen zulässt).
Dewwwald
Funktioniert Bull mit PM2-Clustering? Oder müssen Sie Ihre eigenen Cluster manuell erstellen, wie in der Dokumentation gezeigt?
Shayan Nahrvar
30

Hintergrundjobs stehen nicht in direktem Zusammenhang mit Ihrer Webdienstarbeit, daher sollten sie sich nicht im selben Prozess befinden. Wenn Sie skalieren, wirkt sich die Speichernutzung der Hintergrundjobs auf die Leistung des Webdienstes aus. Sie können sie jedoch in dasselbe Code-Repository stellen, wenn Sie möchten, was auch immer sinnvoller ist.

Eine gute Wahl für das Versenden von Nachrichten zwischen den beiden Prozessen wäre Redis , wenn das gelegentliche Löschen einer Nachricht in Ordnung ist. Wenn Sie "keine Nachricht hinterlassen" möchten, benötigen Sie einen schwereren Broker wie Rabbit . Ihr Webdienstprozess kann veröffentlicht und Ihr Hintergrundjobprozess kann abonniert werden.

Es ist nicht erforderlich, dass die beiden Prozesse gemeinsam gehostet werden. Sie können sich auf separaten VMs und Docker-Containern befinden, unabhängig davon, was Sie verwenden. Auf diese Weise können Sie ohne großen Aufwand skalieren.

wberry
quelle
3
Wirklich die einzige Antwort, die Kaninchen erwähnt hat? Dies ist die Unternehmensantwort. +1
Augie Gardner
11

Wenn Sie MongoDB verwenden, empfehle ich Agenda . Auf diese Weise werden keine separaten Redis-Instanzen ausgeführt und Funktionen wie Zeitplanung, Warteschlange und Web-Benutzeroberfläche sind vorhanden. Die Agenda-Benutzeroberfläche ist optional und kann natürlich separat ausgeführt werden.

Ich würde auch empfehlen, eine lose gekoppelte Abstraktion zwischen Ihrer Anwendungslogik und dem Warteschlangen- / Planungssystem einzurichten, damit das gesamte Hintergrundverarbeitungssystem bei Bedarf ausgetauscht werden kann. Mit anderen Worten, halten Sie so viel Anwendungs- / Verarbeitungslogik von Ihren Agenda-Jobdefinitionen fern, um sie leicht zu halten.

sean2078
quelle
3

Ich möchte vorschlagen, Redis zum Planen von Jobs zu verwenden. Es hat viele verschiedene Datenstrukturen, Sie können immer eine auswählen, die besser zu Ihrem Anwendungsfall passt.

Sie haben RoR und DJ erwähnt, also sind Sie vermutlich mit Sidekiq vertraut. Sie können node-sidekiq für die Jobplanung verwenden, wenn Sie möchten, aber es ist suboptimal imo, da der Hauptzweck darin besteht, nodejs in RoR zu integrieren.

Für die Daemonisierung von Arbeitern würde ich die Verwendung von PM2 empfehlen . Es ist weit verbreitet und wird aktiv gepflegt. Es löst viele Probleme (z. B. Bereitstellung, Überwachung, Clustering), stellen Sie also sicher, dass es kein Overkill für Sie ist.

stefkin
quelle
1

Ich habe Bee-Queue & Bull ausprobiert und mich am Ende für Bull entschieden. Ich habe mich zuerst für die Bienenwarteschlange b / c entschieden, es ist ziemlich einfach, ihre Beispiele sind leicht zu verstehen, während die Beispiele von Bullen etwas kompliziert sind. Bienenwiki Der Ursprung der Bienenwarteschlange schwingt auch mit mir mit. Aber das Problem mit Biene ist, dass <1> ihre Problemlösungszeit ziemlich langsam ist, ihr letztes Update war vor 10 Monaten. <2> Ich kann keine einfache Möglichkeit finden, den Job anzuhalten / abzubrechen.

Auf der anderen Seite aktualisiert Bull häufig seine Codes und reagiert auf Probleme. Laut Node.js Bewertung der Jobwarteschlange ist die Schwäche des Bullen "langsame Problemlösungszeit", aber meine Erfahrung ist das Gegenteil!

Trotzdem ist ihre API ähnlich, so dass es ziemlich einfach ist, von einer zur anderen zu wechseln.

Qiulang
quelle
-6

Ich schlage vor, ein geeignetes Node.js-Framework zu verwenden, um Ihre App zu erstellen.

Ich denke, dass Sails.js das mächtigste und am einfachsten zu bedienende ist .

Es ist ein MVC-Framework. Wenn Sie also an die Entwicklung in ROR gewöhnt sind, werden Sie es sehr, sehr einfach finden!

Wenn Sie es verwenden, ist es bereits ein leistungsstarker (in Javascript ausgedrückt) Jobmanager vorhanden.

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

Wenn Sie weitere Informationen benötigen, zögern Sie nicht, mich zu kontaktieren!

Zio Mak Sò
quelle
5
Ich suche einen Hintergrundprozessmanager für Node. Per Definition sollte dies von Ihrer Web-App getrennt sein. Und es sollte keine Rolle spielen, ob Sie Sails, Express, Hapi oder was auch immer Sie mögen.
Ole Spaarmann
Ok, du kannst Bull oder Webworker-Threads ausprobieren ... viel Glück mit Node.js :)
Zio Mak Sò
Es sieht aus wie Segel.js ist ziemlich groß und macht viel mehr als CronJobs. Ich habe Node-Cron ( github.com/kelektiv/node-cron ) gefunden, von dem ich wette, dass es das ist, was saws.js verwendet.
pbatey