The Cluster module allows Node.js to leverage multi-core systems, improving app performance. Let's explore how to use it effectively.
Why Cluster?
- Utilize all CPU cores
- Improve app responsiveness
- Increase reliability through worker redundancy
Basic Usage
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello World\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
Load Balancing
Node.js handles load balancing automatically using a round-robin approach.
Inter-Process Communication (IPC)
if (cluster.isMaster) {
const worker = cluster.fork();
worker.send('Hi there');
} else {
process.on('message', (msg) => {
console.log('Message from master:', msg);
});
}
Zero-Downtime Restarts
if (cluster.isMaster) {
cluster.on('exit', (worker, code, signal) => {
if (!worker.exitedAfterDisconnect) {
console.log('Worker crashed. Starting a new worker');
cluster.fork();
}
});
process.on('SIGUSR2', () => {
const workers = Object.values(cluster.workers);
const restartWorker = (workerIndex) => {
const worker = workers[workerIndex];
if (!worker) return;
worker.on('exit', () => {
if (!worker.exitedAfterDisconnect) return;
console.log(`Exited process ${worker.process.pid}`);
cluster.fork().on('listening', () => {
restartWorker(workerIndex + 1);
});
});
worker.disconnect();
};
restartWorker(0);
});
}
Best Practices
- Use worker_threads for CPU-intensive tasks
- Implement proper error handling in workers
- Monitor worker health and restart if necessary
- Use a process manager like PM2 for production
Pitfalls to Avoid
- Sharing server handles explicitly (Node.js does this automatically)
- Overusing IPC (can become a bottleneck)
- Neglecting to handle worker crashes
Cluster module is powerful for horizontal scaling, but use judiciously. Always profile to ensure it's solving your specific performance needs.
Cheers🥂