O Node.js é um segmento por processo, mas é absolutamente dimensionável em máquinas com vários núcleos.
Esta é uma decisão de design muito deliberada e elimina a necessidade de lidar com a semântica de bloqueio e eu realmente adoro não mexer com a depuração de código multithread.
E quanto ao escalonamento na carga com o Node? Aqui estão duas opções simples e fáceis de configurar:
Proxy reverso com NGINX
Execute seu serviço Node.js por trás de um proxy reverso como Nginx, bom para limitação de conexão, reescrever URLs, servir conteúdo estático (NGINX é muito melhor do que Node para isso) e fazer proxy de outros sub-serviços. O Nginx capturará seu tráfego da porta 80 e pode ser facilmente configurado para rotear as solicitações para o processo de dois nós em execução em portas diferentes como este:
upstream app {
server localhost:8001;
server localhost:8002;
}
server {
location / {
proxy_pass http://app;
}
}
e, em seguida, inicie seus processos com node PORT=8001 app.js
enode PORT=8002 app.js
Clusters
Da documentação do Node.js:
Uma única instância do Node é executada em um único thread. Para aproveitar as vantagens dos sistemas multi-core, o usuário às vezes vai querer lançar um cluster de processos do Node para lidar com a carga. O módulo de cluster permite que você crie facilmente processos filhos que compartilham portas de servidor.
O uso de cluster permite que você aproveite esse recurso bifurcando um processo seu para cada CPU detectada. Porém, o módulo cluster ainda está em fase experimental, é uma solução, mas geralmente prefiro o primeiro. De qualquer forma, é bom entender seu propósito e comportamento. Uma boa abordagem é ter um arquivo js separado para iniciar seu aplicativo no modo de cluster que seja totalmente opcional e app.js não esteja vinculado de forma alguma a ele. E pode ser assim:app.js
var os = require('os');
var cluster = require('cluster');
// Setup the cluster to use app.js
cluster.setupMaster({
exec: 'app.js'
});
// Monitor dying workers
cluster.on('exit', function(worker) {
console.log('Worker ' + worker.id + ' died');
cluster.fork();
});
// Fork a worker for each available CPU
for (var i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
Este exemplo de cluster foi tirado deste ótimo (boilerplate do hackathon inicial) [ https://github.com/sahat/hackathon-starter ] por Sahat.
Em ambos os casos, você pode usar qualquer armazenamento de sessão como Connect-Mongo , Connect-Redis ou qualquer outro armazenamento de sessão.