Node.js und CPU-intensive Anfragen
Habe ich begonnen zu basteln mit Node.js HTTP-server und wirklich wie das schreiben von server-side Javascript, aber etwas hält mich von ab zu verwenden Node.js für meine web-Anwendung.
Ich verstehe das ganze async-I/O-Konzept, aber ich bin etwas besorgt über die Grenzfälle, wo prozeduralen code ist sehr CPU-intensiv, wie Bildbearbeitung oder das Sortieren großer Datenmengen.
Wie ich es verstehe, wird der server sehr schnell für einfache web-Seite Anfragen, wie die Anzeige einer Liste der Benutzer oder Leser eines blog-post. Allerdings, wenn ich schreiben möchte sehr CPU-intensiven code (im admin-back-end zum Beispiel), die generiert Grafiken oder ändert, Tausende von Bildern, die Anfrage wird sehr langsam (ein paar Sekunden). Da dieser code ist nicht async, alle Anfragen an den server während dieser wenigen Sekunden wird blockiert, bis langsam meine Anfrage ist erledigt.
Ein Vorschlag war der Einsatz von Web-Arbeiter für CPU-intensive Aufgaben. Aber ich fürchte, web-Arbeitnehmer machen es schwer zu schreiben sauberen code, da es funktioniert, indem Sie eine separate JS-Datei. Was ist, wenn die CPU-intensive code befindet sich in einem Objekt Methode? Es Art von saugt, schreiben Sie eine JS-Datei, die für jede Methode, die ist CPU-intensiv.
Ein anderer Vorschlag war, um zu laichen einen Kind-Prozess, aber das macht den code noch weniger wartbar zu sein.
Irgendwelche Vorschläge, um diese zu überwinden (wahrgenommene) Hindernis? Wie du schreibst sauberen Objekt-orientierten code mit Node.js während Sie sicherstellen, dass CPU-Intensive Aufgaben ausgeführt werden, async?
InformationsquelleAutor der Frage Olivier Lalonde | 2010-08-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was Sie brauchen, ist ein task-queue! Bewegen Sie Ihre lang Laufenden Aufgaben aus dem web-server ist eine GUTE Sache. Um jede Aufgabe in "eigene" js-Datei fördert Modularität und Wiederverwendung von code. Es zwingt Sie, sich zu überlegen, wie strukturieren Sie Ihr Programm in einer Weise, die macht es einfacher zu Debuggen und pflegen Sie langfristig. Ein weiterer Vorteil einer task-queue ist der Arbeitnehmer geschrieben werden können in einer anderen Sprache. Nur pop-eine Aufgabe, die Arbeit zu tun, und schreiben Sie die Antwort zurück.
sowas https://github.com/resque/resque
Hier ist ein Artikel von github, warum Sie es gebaut http://github.com/blog/542-introducing-resque
InformationsquelleAutor der Antwort Tim
Dies ist ein Missverständnis der definition von web-server-es sollte nur verwendet werden, um "talk" mit den Kunden. Schwerlast-Aufgaben sollten delegiert werden, um eigenständige Programme (das kann natürlich auch sein, geschrieben in JS).
Sie würden wahrscheinlich sagen, dass es schmutzig ist, aber ich versichere Ihnen, dass ein web-server-Prozess stecken, in der die Größenänderung von Bildern ist nur noch schlimmer (auch für sagen wir Apache, wenn es blockiert nicht die anderen Abfragen). Dennoch kann man die Nutzung einer gemeinsamen Bibliothek zur Vermeidung von code-Redundanz.
EDIT: ich habe mit einer Analogie; web-Anwendung sein soll als ein restaurant. Sie haben die Kellner (web-server) und Köche (Arbeitnehmer). Die Kellner sind in Kontakt mit den Kunden und machen einfache Aufgaben wie das bereitstellen-Menü oder erklären, wenn einige Gericht ist vegetarisch. Auf der anderen Seite delegieren Sie schwieriger Aufgaben in die Küche. Weil die Kellner sind nur einfache Dinge, die Sie schnell reagieren, und die Köche können sich auf Ihre Arbeit.
Node.js hier wäre eine einzige, aber sehr talentierten Kellner, die viele Anforderungen gleichzeitig, und Apache wäre eine Bande von dumb-Kellner, die nur eine Anfrage jeder. Wenn diese einem Node.js Kellner beginnen würde zu Kochen, wäre es eine unmittelbare Katastrophe. Noch Kochen könnte auch der Auspuff auch ein großes Angebot von Apache Kellner, nicht zu erwähnen das chaos in der Küche und die fortschreitende Abnahme der Ansprechempfindlichkeit.
InformationsquelleAutor der Antwort mbq
Sie nicht möchten, dass Ihre CPU-intensiven code für die Ausführung von asynchronen, Sie wollen es ausführen parallel. Sie benötigen, um die Verarbeitung zu arbeiten aus dem thread, der mit HTTP-requests. Es ist der einzige Weg, um dieses problem zu lösen. Mit NodeJS ist die Antwort, die cluster-Modul, zum starten von child-Prozessen zu tun, die schweres heben. (AFAIK Knoten haben kein Konzept von threads/shared memory; es Prozesse oder gar nichts). Sie haben zwei Möglichkeiten, wie Sie die Struktur Ihrer Anwendung. Sie können die 80/20-Lösung von Laich-8 HTTP-Server und der Umgang mit rechenintensiven Aufgaben synchron auf die Kind-Prozesse. Tun, ist ziemlich einfach. Sie könnte eine Stunde dauern, zu Lesen, über die es zu diesem link. In der Tat, wenn Sie einfach nur Abzocke der Beispiel-code oben, dass link erhalten Sie 95% der Weg dorthin.
Den anderen Weg, um Struktur dies ist das einrichten einer job-Warteschlange und das senden von großen compute-Aufgaben, die über die Warteschlange. Beachten Sie, dass es eine Menge overhead im Zusammenhang mit der IPC für eine job-queue, so ist dies nur sinnvoll, wenn die Aufgaben sind wesentlich größer als der Aufwand.
Ich bin überrascht, dass keiner dieser anderen Antworten auch erwähnen cluster.
Hintergrund:
Asynchroner code ist code, der hält, bis etwas passiert woanders, an welcher Stelle der code erwacht und setzt die Ausführung Fort. Ein sehr häufiger Fall, wo etwas, das langsam geschehen muss, woanders ist I/O.
Asynchronen code ist nicht hilfreich, wenn es Prozessor , ist verantwortlich für die Arbeit. Genau das ist der Fall bei "rechenintensiven" Aufgaben.
Nun könnte es scheinen, dass der asynchrone code Nische, aber in der Tat ist es sehr üblich. Es passiert einfach nicht nützlich zu sein für die rechenintensiven Aufgaben.
Warten auf I/O ist ein Muster, das passiert immer in web-Server, zum Beispiel. Jeder client, der eine Verbindung zu Ihrem Server bekommt eine Buchse. Die meisten der Zeit, die buchsen sind leer. Sie wollen nicht, etwas zu tun, bis ein socket empfängt einige Daten, an welcher Stelle Sie wollen, um die Anfrage zu behandeln. Unter der Haube ein HTTP-server wie ein Knoten, ist die Verwendung eines Vielseitigkeits-Bibliothek (libev) zu verfolgen, die Tausende von open sockets. Die OS informiert libev und dann libev benachrichtigt, NodeJS, wenn einem der sockets Daten bekommt, und dann NodeJS stellt eine Veranstaltung auf der event-queue, und Ihre http-code setzt bei diesem Punkt an und behandelt die Ereignisse eines nach dem anderen. Ereignisse, die nicht bekommen, setzen Sie auf die Warteschlange, bis der socket hat einige Daten, also Ereignisse sind nie warten auf Daten - es ist bereits für Sie da.
Single threaded event-basierte web-Server sinnvoll als Paradigma, wenn der Flaschenhals ist das warten auf ein Bündel von meist leeren socket-verbindungen und Sie nicht möchten, dass ein ganzer thread oder Prozess für jede Verbindung im Leerlauf, und Sie wollen nicht zu Umfrage Ihre 250k-buchsen zu finden, das nächste, das Daten enthält.
InformationsquelleAutor der Antwort masonk
Paar Ansätze, die Sie verwenden können.
Als @Tim Notizen erstellen, können Sie eine asynchrone Aufgabe, die sich außerhalb oder parallel zu Ihrem Haupt-portion Logik. Kommt auf deine genauen Anforderungen, aber auch cron kann als ein queueing-Mechanismus.
WebWorker arbeiten können für die asynchrone Prozesse, aber Sie sind derzeit nicht unterstützt node.js. Es gibt ein paar Erweiterungen, die Unterstützung bieten, zum Beispiel: http://github.com/cramforce/node-worker
Erhalten Sie weiterhin können Sie noch die Wiederverwendung von Modulen und code über den standard - "Bedarf" - Mechanismus. Sie müssen nur sicherstellen, dass die ursprünglichen Versand an den Arbeitnehmer übergibt alle Informationen, die benötigt werden, um die Ergebnisse verarbeiten.
InformationsquelleAutor der Antwort Toby Hede