Freunde, die NodeJs verwenden, wissen, dass der Knoten einsthread ist, was bedeutet, dass Sie beim Ausführen einer 8-Core-CPU nur die Rechenleistung eines Kerns verwenden können.
Single Threading war schon immer eine Kritik an Knoten, aber mit der Einführung von Cluster in Version 0.6 hat sich diese Situation geändert. Entwickler können sich auf Cluster verlassen, um ihren Knotenserver einfach auf Multi-Thread-Server zu erweitern.
Was ist Cluster
Cluster ist eine von Knoten bereitgestellte Multi-Threaden-Bibliothek. Benutzer können damit mehrere Threads erstellen. Themen teilen sich einen Höranschluss. Wenn dieser Port eine externe Anfrage vorliegt, leitet Cluster die Anfrage an einen zufälligen Thread weiter. Da jeder Knoten -Thread zehn Megabyte Speicher einnimmt, ist es unmöglich, für jede Anforderung wie PHP einen Thread zu erstellen. Im Allgemeinen überschreitet die Anzahl der erstellten Threads die Anzahl der CPU -Kerne höchstens.
Die Codekopie lautet wie folgt:
var cluster = required ('cluster');
var http = required ('http');
var numcpus = required ('os'). cpus (). Länge;
if (cluster.ismaster) {
// Gabelarbeiter.
für (var i = 0; i <numcpus; i ++) {
cluster.fork ();
}
cluster.on ('exit', function (Worker, Code, Signal) {
console.log ('Worker' + Worker.Process.pid + 'Die');
});
} anders {
// Arbeitnehmer können jede TCP -Verbindung teilen
// In diesem Fall ist es ein HTTP -Server
http.createServer (Funktion (req, res) {{
Res.WriteHead (200);
res.end ("Hello World/n");
}). Hören (8000);
}
Wie im obigen Code gezeigt, wird cluster.ismaster auf true gesetzt, wenn das Programm ausgeführt wird. Nach dem Aufrufen von cluster.fork () erstellt das Programm einen Thread und führt ihn erneut aus. Zu diesem Zeitpunkt wird Cluster.ismaster auf false eingestellt. Wir verwenden diese Variable hauptsächlich, um festzustellen, ob der aktuelle Thread zu einem untergeordneten Thread gehört.
Es kann auch angemerkt werden, dass nach dem Erstellen jedes untergeordneten Threads Port 8000 anhört, ohne Konflikte zu verursachen. Dies ist die Funktion von Cluster -Shared -Ports.
Kommunikation zwischen Themen
Wenn Themen erstellt werden, teilen sie keinen Speicher oder Daten miteinander. Alle Datenaustausch können nur im Haupt -Thread über Worker.send und Worker.on ('Nachricht', Handler) verarbeitet werden. Im Folgenden sind ein Beispiel für ein Broadcast -System aufgeführt.
Die Codekopie lautet wie folgt:
var cluster = required ('cluster');
var http = required ('http');
var numcpus = required ('os'). cpus (). Länge;
if (cluster.ismaster) {
var Arbeiter = [];
// Erstellen Sie einen neuen Arbeiter
Funktion newworker () {
var Worker = cluster.fork ();
// Informationen hören. Wenn der Typ ausgestrahlt wird, wird er als Sendung bestimmt
Worker.on ('Nachricht', Funktion (msg) {
if (msg.type == 'sendest') {
var event = msg.event;
// Sende diese Sendung an alle Arbeiter
Arbeiter.foreach (Funktion (Arbeiter) {
Worker.Send (Ereignis);
})
}
});
Rückkehrarbeiter;
}
für (var i = 0; i <numcpus; i ++) {
Workers.push (NewWorder ());
}
cluster.on ('Online', Funktion (Arbeiter) {
console.log ("Arbeiter %d ist online", Worker.id);
})
} anders {
var Worker = cluster.worker;
// Broadcast soll eine Nachricht mit Typsübertragung senden. Ereignis ist Broadcast -Inhalte
Worker.Broadcast = Funktion (Ereignis) {
Worker.send ({{
Typ: 'Broadcast',
Veranstaltung: Ereignis
});
}
// Dies ist nicht möglich, die zurückgegebenen Informationen mit Worker.on hier anzuhören.
process.on ('message', function (Ereignis) {
console.log ('Worker:'+Worker.id+'wiederhergestelltes Ereignis von'+Event.WormerId);
})
// Sendung senden
Worker.Broadcast ({{
Nachricht: 'Online',
Workerid: Worker.id
})
}
Probleme, die sich bewusst sind
Es wird auch oben erwähnt, dass Daten nicht zwischen Threads geteilt werden können und alle Datenaustausche nur durch die Kommunikation zwischen Threads ausgetauscht werden können. Darüber hinaus sind die ausgetauschten Daten serialisierbar, so dass Funktionen, Dateideskriptoren und HttPesponse nicht übergeben werden können.
Wenn Sie Cluster verwenden, müssen Sie das Datenaustauschproblem beim Entwerfen des Programms berücksichtigen. Mein eigener Ansatz ist es, alle Daten ähnlich der Sitzung in Redis zu speichern, und jeder Thread erledigt die Speicher- und Rückzugsarbeit, und alle Daten werden nicht im Knotenspeicher platziert.
Der letzte Punkt, Cluster ist derzeit offiziell als experimentell vom Knoten markiert, und die API kann sich in Zukunft ändern.