[ Dieser Beitrag ist ab dem 02.09.2012 auf dem neuesten Stand (neuer als oben). ]]
Node.js skaliert absolut auf Multi-Core-Maschinen.
Ja, Node.js ist ein Thread pro Prozess. Dies ist eine sehr bewusste Entwurfsentscheidung und macht die Sperrsemantik überflüssig. Wenn Sie damit nicht einverstanden sind, wissen Sie wahrscheinlich noch nicht, wie wahnsinnig schwierig es ist, Multithread-Code zu debuggen. Eine ausführlichere Erklärung des Node.js-Prozessmodells und warum es so funktioniert (und warum es NIEMALS mehrere Threads unterstützt), finden Sie in meinem anderen Beitrag .
Wie nutze ich meine 16-Core-Box?
Zwei Wege:
- Für große, schwere Rechenaufgaben wie die Bildcodierung kann Node.js untergeordnete Prozesse starten oder Nachrichten an zusätzliche Arbeitsprozesse senden. In diesem Entwurf muss ein Thread den Ablauf von Ereignissen und N Prozessen verwalten, die schwere Rechenaufgaben ausführen und die anderen 15 CPUs zerkauen.
- Um den Durchsatz auf einem Webservice 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 Kernanzahl.
Skalieren des Durchsatzes auf einem Webservice
Seit v6.0.X hat Node.js das Cluster-Modul sofort integriert, wodurch es einfach ist, mehrere Node-Worker einzurichten, die einen einzelnen Port überwachen können. Beachten Sie, dass dies NICHT dasselbe ist wie das ältere Learnboost-Cluster-Modul, das über npm verfügbar ist .
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
Die Mitarbeiter konkurrieren um die Annahme neuer Verbindungen, und der am wenigsten belastete Prozess wird höchstwahrscheinlich gewinnen. Es funktioniert ziemlich gut und kann den Durchsatz auf einer Multi-Core-Box recht gut skalieren.
Wenn Sie genug Last haben, um sich um mehrere Kerne zu kümmern, sollten Sie noch ein paar Dinge tun:
Führen Sie Ihren Node.js-Dienst hinter einem Webproxy wie Nginx oder Apache aus - etwas, das die Verbindungsdrosselung durchführen kann (es sei denn, Sie möchten, dass die Überlastungsbedingungen die Box vollständig herunterfahren), URLs neu schreiben, statischen Inhalt bereitstellen und andere Unterdienste vertreten.
Recyceln Sie regelmäßig Ihre Arbeitsprozesse. Bei einem lang laufenden Prozess summiert sich möglicherweise sogar ein kleiner Speicherverlust.
Protokollsammlung / -überwachung einrichten
PS: Es gibt eine Diskussion zwischen Aaron und Christopher in den Kommentaren eines anderen Beitrags (zum Zeitpunkt dieses Schreibens ist es der oberste Beitrag). Ein paar Kommentare dazu:
- Ein Shared-Socket-Modell ist sehr praktisch, damit mehrere Prozesse einen einzelnen Port überwachen und um die Annahme neuer Verbindungen konkurrieren können. Konzeptionell könnte man sich vorstellen, dass Apache dies mit der erheblichen Einschränkung tut, dass jeder Prozess nur eine einzige Verbindung akzeptiert und dann stirbt. Der Effizienzverlust für Apache ist mit dem Verzweigen neuer Prozesse verbunden und hat nichts mit den Socket-Operationen zu tun.
- Für Node.js ist es eine äußerst vernünftige Lösung, wenn N-Mitarbeiter an einem einzigen Socket miteinander konkurrieren. Die Alternative besteht darin, ein On-Box-Front-End wie Nginx einzurichten und diesen Proxy-Verkehr an die einzelnen Mitarbeiter weiterzuleiten, wobei zwischen Arbeitnehmern gewechselt wird, um neue Verbindungen zuzuweisen. Die beiden Lösungen weisen sehr ähnliche Leistungsmerkmale auf. Und da Sie, wie oben erwähnt, wahrscheinlich Nginx (oder eine Alternative) haben möchten, das Ihren Knotendienst bedient, haben Sie hier wirklich die Wahl zwischen:
Gemeinsame Ports: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
vs.
Einzelne Ports: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
Die Einrichtung der einzelnen Ports bietet möglicherweise einige Vorteile (möglicherweise weniger Kopplung zwischen Prozessen, differenziertere Entscheidungen zum Lastenausgleich usw.), aber die Einrichtung ist definitiv aufwändiger und das integrierte Cluster-Modul ist niedrig -Komplexitätsalternative, die für die meisten Menschen funktioniert.