Les amis qui utilisent NodeJS savent tous que le nœud est unique, ce qui signifie que lorsque vous exécutez un processeur à 8 cœurs, vous ne pouvez utiliser que la puissance de calcul d'un noyau.
Le threading unique a toujours été une critique des nœuds, mais avec l'introduction du cluster dans la version 0.6, cette situation a changé. Les développeurs peuvent compter sur le cluster pour étendre facilement leur serveur de nœuds vers un serveur multi-thread.
Qu'est-ce que le cluster
Le cluster est une bibliothèque multi-thread fournie par Node. Les utilisateurs peuvent l'utiliser pour créer plusieurs threads. Les fils partagent un port d'écoute. Lorsqu'il y a une demande externe à ce port, le cluster transmetra la demande à un thread aléatoire. Étant donné que chaque thread de nœud occupera des dizaines de mégaoctets de mémoire, il est impossible de créer un thread pour chaque demande comme PHP. D'une manière générale, le nombre de threads créés ne dépassera pas le nombre de cœurs CPU au maximum.
La copie de code est la suivante:
var cluster = require ('cluster');
var http = require ('http');
var numcpus = require ('os'). CPU (). Longueur;
if (cluster.ismaster) {
// fourche des travailleurs.
pour (var i = 0; i <numcpus; i ++) {
cluster.Fork ();
}
cluster.on ('exit', fonction (travailleur, code, signal) {
Console.log ('Worker' + Worker.Process.pid + 'Die');
});
} autre {
// Les travailleurs peuvent partager n'importe quelle connexion TCP
// Dans ce cas, c'est un serveur HTTP
http.createServer (fonction (req, res) {
res.writehead (200);
res.end ("Hello World / N");
}). écouter (8000);
}
Comme indiqué dans le code ci-dessus, Cluster.ismaster sera défini sur true lors de l'exécution du programme. Après avoir appelé Cluster.Fork (), le programme créera un thread et le réévaluera. À l'heure actuelle, Cluster.ismaster sera défini sur FAUX. Nous utilisons principalement cette variable pour déterminer si le thread actuel appartient à un fil d'enfant.
On peut également noter qu'après la création de chaque fil d'enfant, il écoutera le port 8000 sans provoquer de conflits. Il s'agit de la fonction des ports partagés en grappe.
Communication entre les fils
Lorsque des threads sont créés, ils ne partagent pas de mémoire ou de données les uns avec les autres. Tous les échanges de données ne peuvent être traités que dans le thread principal via Worker.Send et Worker.on ('Message', Handler). Le suivant répertorie un exemple de système de diffusion.
La copie de code est la suivante:
var cluster = require ('cluster');
var http = require ('http');
var numcpus = require ('os'). CPU (). Longueur;
if (cluster.ismaster) {
var travailleurs = [];
// Créer un nouveau travailleur
fonction newworker () {
var worker = cluster.fork ();
// écoute des informations. Si le type est diffusé, il sera déterminé comme une diffusion
worker.on ('message', fonction (msg) {
if (msg.type == 'Broadcast') {
var event = msg.event;
// Envoyez cette diffusion à tous les travailleurs
Workers.ForEach (fonction (travailleur) {
wearch.send (événement);
})
}
});
travailleur de retour;
}
pour (var i = 0; i <numcpus; i ++) {
workers.push (newworker ());
}
cluster.on ('en ligne', fonction (travailleur) {
Console.log («Worker% D est en ligne», Worker.ID);
})
} autre {
var worker = cluster.worker;
// La diffusion est d'envoyer un message avec le type de diffusion, l'événement est du contenu de diffusion
wearch.broadcast = fonction (événement) {
wearch.send ({
Type: «diffusion»,
événement: événement
});
}
// Ce n'est pas possible d'écouter les informations retournées en utilisant Worker.on ici.
process.on ('message', fonction (événement) {
Console.log ('Worker:' + Worker.id + 'a récupéré l'événement de' + event.workerid);
})
// Envoyer la diffusion
wearch.broadcast ({
Message: «en ligne»,
WorkerId: Worker.id
})
}
Problèmes à connaître
Il est également mentionné ci-dessus que les données ne peuvent pas être partagées entre les threads, et tous les échanges de données ne peuvent être échangés que par la communication entre les threads. De plus, les données échangées sont sérialisables, donc les fonctions, les descripteurs de fichiers et la HTTPResponse ne peuvent pas être passées.
Si vous utilisez un cluster, vous devez considérer le problème d'échange de données lors de la conception du programme. Ma propre approche consiste à stocker toutes les données similaires à la session dans Redis, et chaque thread fait le travail de stockage et de retrait, et toutes les données ne sont pas placées dans la mémoire du nœud.
Dernier point, le cluster est actuellement officiellement marqué comme expérimental par le nœud, et l'API pourrait changer à l'avenir.