Amigos que usam o NodeJs sabem que o nó é thread único, o que significa que, ao executar em uma CPU de 8 núcleos, você pode usar apenas o poder de computação de um núcleo.
O encadeamento único sempre foi uma crítica aos nós, mas com a introdução do cluster na versão 0.6, essa situação mudou. Os desenvolvedores podem confiar no cluster para expandir facilmente seu servidor de nó para o servidor multithread.
O que é cluster
O cluster é uma biblioteca multi-thread fornecida pelo nó. Os usuários podem usá -lo para criar vários threads. Os tópicos compartilham uma porta de escuta. Quando houver uma solicitação externa a esta porta, o cluster encaminhará a solicitação para um thread aleatório. Como cada encadeamento de nó ocupará dezenas de megabytes de memória, é impossível criar um thread para cada solicitação como o PHP. De um modo geral, o número de threads criados não excederá o número de núcleos da CPU no máximo.
A cópia do código é a seguinte:
var cluster = requer ('cluster');
var http = requer ('http');
var numcpus = requer ('os'). cpus (). comprimento;
if (cluster.ismaster) {
// Forks Forks.
for (var i = 0; i <numcpus; i ++) {
cluster.fork ();
}
cluster.on ('exit', função (trabalhador, código, sinal) {
console.log ('trabalhador' + trabalhador.process.pid + 'die');
});
} outro {
// Os trabalhadores podem compartilhar qualquer conexão TCP
// neste caso, é um servidor http
http.createServer (function (req, res) {
Res.Writehead (200);
res.nd ("Hello World/n");
}). Ouça (8000);
}
Conforme mostrado no código acima, o cluster.ismaster será definido como true quando o programa estiver em execução. Depois de ligar para o cluster.fork (), o programa criará um thread e o executará novamente. No momento, o cluster.ismaster será definido como falso. Usamos principalmente essa variável para determinar se o encadeamento atual pertence a um thread infantil.
Também se pode notar que, depois que cada tópico infantil for criado, ele ouvirá a porta 8000 sem causar conflitos. Esta é a função das portas compartilhadas do cluster.
Comunicação entre threads
Quando os threads são criados, eles não compartilham memória ou dados entre si. Toda a troca de dados só pode ser processada no encadeamento principal através do trabalhador.send e trabalhador.on ('mensagem', manipulador). O seguinte lista um exemplo de um sistema de transmissão.
A cópia do código é a seguinte:
var cluster = requer ('cluster');
var http = requer ('http');
var numcpus = requer ('os'). cpus (). comprimento;
if (cluster.ismaster) {
Var Workers = [];
// Crie um novo trabalhador
função newworker () {
var trabalhador = cluster.fork ();
// Ouça informações. Se o tipo for transmitido, ele será determinado como uma transmissão
trabalhador.on ('mensagem', função (msg) {
if (msg.type == 'transmissão') {
var evento = msg.event;
// Envie esta transmissão para todos os trabalhadores
trabalhadores.ForEach (função (trabalhador) {
trabalhador.send (evento);
})
}
});
trabalhador de volta;
}
for (var i = 0; i <numcpus; i ++) {
trabalhadores.push (newworker ());
}
cluster.on ('online', função (trabalhador) {
console.log ('trabalhador %d está online', trabalhador.id);
})
} outro {
var trabalhador = cluster.worker;
// A transmissão é enviar uma mensagem com transmissão do tipo, o evento é o conteúdo da transmissão
trabalhador.broadcast = function (evento) {
trabalhador.send ({
Tipo: 'Broadcast',
Evento: evento
});
}
// Isso não é possível ouvir as informações retornadas usando o trabalhador.on aqui.
process.on ('mensagem', função (evento) {
console.log ('trabalhador:'+trabalhador.id+'Evento recuperado de'+event.workerid);
})
// Enviar transmissão
trabalhador.broadcast ({
Mensagem: 'Online',
trabalhador: trabalhador.id
})
}
Questões a serem cientes
Também é mencionado acima que os dados não podem ser compartilhados entre os threads, e todas as trocas de dados só podem ser trocadas através da comunicação entre threads. Além disso, os dados trocados são serializáveis, portanto, funções, descritores de arquivos e HTTPRESPONSE não podem ser aprovados.
Se você usar o cluster, precisará considerar o problema da troca de dados ao projetar o programa. Minha abordagem é armazenar todos os dados semelhantes à sessão no Redis, e cada thread faz o trabalho de armazenamento e retirada, e todos os dados não são colocados na memória do nó.
No último ponto, o cluster é atualmente marcado oficialmente como experimental pelo nó, e a API pode mudar no futuro.