
Zaharpopov
Node.js sieht interessant aus, ABER Ich muss etwas übersehen – ist Node.js nicht darauf abgestimmt, nur auf einem einzelnen Prozess und Thread ausgeführt zu werden?
Wie skaliert es dann für Multi-Core-CPUs und Multi-CPU-Server? Immerhin ist es toll, Single-Thread-Server möglichst schnell zu machen, aber für hohe Lasten würde ich mehrere CPUs einsetzen wollen. Und das Gleiche gilt für die Beschleunigung von Anwendungen – heute scheint der Weg darin zu bestehen, mehrere CPUs zu verwenden und die Aufgaben zu parallelisieren.
Wie passt Node.js in dieses Bild? Ist seine Idee, irgendwie mehrere Instanzen zu verteilen, oder was?

David Dopson
[This post is up-to-date as of 2012-09-02 (newer than above).]
Node.js skaliert absolut auf Mehrkernmaschinen.
Ja, Node.js ist ein Thread pro Prozess. Dies ist eine sehr bewusste Entwurfsentscheidung und beseitigt die Notwendigkeit, sich mit Sperrsemantik zu befassen. Wenn Sie dem nicht zustimmen, wissen Sie wahrscheinlich noch nicht, wie wahnsinnig schwer es ist, Multithread-Code zu debuggen. Für eine tiefere Erklärung des Node.js-Prozessmodells und warum es so funktioniert (und warum es NIEMALS mehrere Threads unterstützen wird), lesen Sie meinen anderen Beitrag.
Wie nutze ich also meine 16-Core-Box?
Zwei Wege:
- Für große Rechenaufgaben wie die Bildcodierung kann Node.js untergeordnete Prozesse starten oder Nachrichten an zusätzliche Worker-Prozesse senden. In diesem Design hätten Sie einen Thread, der den Ereignisfluss verwaltet, und N Prozesse, die schwere Rechenaufgaben erledigen und die anderen 15 CPUs belasten.
- Um den Durchsatz auf einem Webdienst zu skalieren, sollten Sie mehrere Node.js-Server auf einer Box ausführen, einen pro Kern, und den Anforderungsverkehr zwischen ihnen aufteilen. Dies bietet eine hervorragende CPU-Affinität und skaliert den Durchsatz nahezu linear mit der Anzahl der Kerne.
Skalieren des Durchsatzes auf einem Webdienst
Seit v6.0.X ist Node.js enthalten das Clustermodul sofort einsatzbereit, was es einfach macht, mehrere Node-Worker einzurichten, die auf einem einzelnen Port lauschen können. Beachten Sie, dass dies NICHT dasselbe ist wie das ältere Learnboost-Modul “Cluster”, das über verfügbar ist npm.
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
Worker konkurrieren darum, neue Verbindungen zu akzeptieren, und der am wenigsten belastete Prozess gewinnt am ehesten. Es funktioniert ziemlich gut und kann den Durchsatz auf einer Multi-Core-Box ziemlich gut skalieren.
Wenn Sie genug Last haben, um sich um mehrere Kerne zu kümmern, sollten Sie auch noch ein paar Dinge tun:
-
Führen Sie Ihren Node.js-Dienst hinter einem Webproxy wie z Nginx oder Apache – etwas, das Verbindungsdrosselung bewirken kann (es sei denn, Sie möchten, dass Überlastbedingungen die Box vollständig zum Erliegen bringen), URLs umschreiben, statische Inhalte bereitstellen und andere Unterdienste weiterleiten.
-
Recyceln Sie regelmäßig Ihre Worker-Prozesse. Bei einem lang andauernden Prozess summiert sich schließlich sogar ein kleines Speicherleck.
-
Log-Sammlung/-Überwachung einrichten
PS: Es gibt eine Diskussion zwischen Aaron und Christopher in den Kommentaren eines anderen Posts (zum jetzigen Zeitpunkt ist es der oberste Post). Ein paar Anmerkungen dazu:
- Ein Shared-Socket-Modell ist sehr praktisch, um es mehreren Prozessen zu ermöglichen, auf einem einzigen Port zu lauschen und um die Annahme neuer Verbindungen zu konkurrieren. Konzeptionell könnte man sich vorstellen, dass Apache dies vorab gegabelt tut, mit der erheblichen Einschränkung, dass jeder Prozess nur eine einzige Verbindung akzeptiert und dann stirbt. Der Effizienzverlust für Apache liegt im Overhead beim Forken neuer Prozesse und hat nichts mit den Socket-Operationen zu tun.
- Für Node.js ist es eine äußerst vernünftige Lösung, N Worker auf einem einzigen Socket konkurrieren zu lassen. Die Alternative besteht darin, ein On-Box-Front-End wie Nginx einzurichten und diesen Proxy-Verkehr zu den einzelnen Workern zu leiten, wobei zwischen den Workern gewechselt wird, um neue Verbindungen zuzuweisen. Die beiden Lösungen haben sehr ähnliche Leistungsmerkmale. Und da Sie, wie ich oben erwähnt habe, wahrscheinlich sowieso Nginx (oder eine Alternative) vor Ihrem Knotendienst haben möchten, haben Sie hier wirklich die Wahl zwischen:
Freigegebene Ports: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
vs
Einzelne Häfen: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
Es gibt wohl einige Vorteile für die Einrichtung einzelner Ports (möglicherweise weniger Kopplung zwischen Prozessen, ausgefeiltere Lastausgleichsentscheidungen usw.), aber die Einrichtung ist definitiv arbeitsaufwändiger und das integrierte Clustermodul ist niedrig -Komplexitätsalternative, die für die meisten Menschen funktioniert.
Eine Methode wäre, mehrere Instanzen von node.js auf dem Server auszuführen und ihnen dann einen Load Balancer (vorzugsweise einen nicht blockierenden wie nginx) vorzusetzen.

broofa
Ryan Dahl beantwortet diese Frage in der Tech-Talk, den er bei Google hielt letzten Sommer. Um es anders auszudrücken: “Führen Sie einfach mehrere Knotenprozesse aus und verwenden Sie etwas Vernünftiges, um ihnen die Kommunikation zu ermöglichen, z. B. sendmsg()-artiges IPC oder traditionelles RPC”.
Wenn Sie sich gleich die Hände schmutzig machen wollen, schauen Sie sich das an Funke2 Für immer Modul. Es macht das Spawnen mehrerer Knotenprozesse trivial einfach. Es übernimmt die Einrichtung der Portfreigabe, sodass sie jeweils Verbindungen zum selben Port akzeptieren können, und auch das automatische Respawnen, wenn Sie sicherstellen möchten, dass ein Prozess neu gestartet wird, wenn er stirbt.
UPDATE – 11.10.11: Konsens in der Node-Community scheint das zu sein Cluster ist jetzt das bevorzugte Modul für die Verwaltung mehrerer Knoteninstanzen pro Maschine. Für immer ist auch einen blick wert.

Sergej Schukow
Sie können verwenden Cluster Modul. Überprüfen Das.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}

Toumi
Node Js unterstützt Clustering, um die Vorteile Ihrer CPU voll auszuschöpfen. Wenn Sie es nicht mit Cluster ausführen, verschwenden Sie wahrscheinlich Ihre Hardwarekapazitäten.
Clustering in Node.js ermöglicht es Ihnen, separate Prozesse zu erstellen, die denselben Serverport teilen können. Wenn wir beispielsweise einen HTTP-Server auf Port 3000 ausführen, handelt es sich um einen Server, der auf einem einzelnen Thread auf einem einzelnen Prozessorkern ausgeführt wird.
Der unten gezeigte Code ermöglicht es Ihnen, Ihre Anwendung zu clustern. Dieser Code ist offizieller Code, der durch Node.js dargestellt wird.
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
Object.keys(cluster.workers).forEach(function(id) {
console.log("I am running with ID : " + cluster.workers[id].process.pid);
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
//Do further processing.
}
Lesen Sie diesen Artikel vollständig Lernprogramm

CyberFonic
Multi-Node nutzt alle Kerne, die Sie möglicherweise haben.
Schau mal rein http://github.com/kriszyp/multi-node.
Für einfachere Anforderungen können Sie mehrere Knotenkopien auf verschiedenen Portnummern starten und ihnen einen Load Balancer vorschalten.
Wie oben erwähnt, Cluster skaliert und verteilt Ihre App über alle Kerne hinweg.
Hinzufügen von etwas wie
cluster.on('exit', function () {
cluster.fork();
});
Wird alle fehlerhaften Worker neu starten.
Heutzutage bevorzugen viele Leute auch PM2die das Clustering für Sie übernimmt und auch bereitstellt einige coole Überwachungsfunktionen.
Fügen Sie dann Nginx oder HAProxy vor mehreren Computern hinzu, auf denen Clustering ausgeführt wird, und Sie haben mehrere Failover-Ebenen und eine viel höhere Lastkapazität.
10015900cookie-checkNode.js auf Mehrkernmaschinenyes
Es sieht so aus, als ob Ryah ernsthaft damit beginnt, integrierte Multi-Core-Unterstützung in den Knoten aufzunehmen: github.com/joyent/node/commit/…
– broofa
13. Oktober 2011 um 21:37 Uhr
Der PM2-Prozessmanager verwendet das Clustermodul intern, um Ihre NodeJS-Apps auf alle verfügbaren Kerne zu verteilen: github.com/Unitech/pm2
– Unitech
14. April 2014 um 5:49 Uhr
@broofa, das sind keine echten Threads und untergeordnete Prozesse haben keinen gemeinsamen Speicher. Siehe auch Was ist das Nodejs-Äquivalent zu Javas echtem Threading und flüchtig-statischen Variablen?.
– Schrittmacher
28. Februar 2017 um 15:27 Uhr