Node.js Cluster Module

Java FileNode.js built-in modules


Node.js'sclusterThe module allows you to easily create worker processes that share the same server port. Since Node.js is single-threaded,clusterThe module can help us fully utilize the performance of multi-core CPU systems.

In simple terms,clusterThe module is like a restaurant manager: it creates multiple waiters (workers) to handle customers (requests), instead of letting one waiter handle all customers.


Why do you need the Cluster module?

  1. Improve performance: Modern CPUs usually have multiple cores, but Node.js uses only one core by default.clusterThe module allows you to utilize all available CPU cores.

  2. Improve reliability: If one worker crashes, other workers can continue handling requests, and the master process can restart the crashed worker.

  3. Zero downtime: You can restart workers one by one to update code without interrupting the service.


Basic usage of the Cluster module

Example

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`Master process ${process.pid}is running`);

  // Fork worker processes
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid}has exited`);
  });
} else {
  // Workers can share the same TCP connection
  // This is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello world\n');
  }).listen(8000);

  console.log(`Worker ${process.pid}has started`);
}

Core concepts analysis

Master Process

  • Responsible for managing all worker processes
  • Usually does not handle actual requests
  • Can listen to various worker events

Worker Process

  • Child processes that actually handle requests
  • Each worker is an independent Node.js process
  • Share the same server port

Common APIs of the Cluster module

cluster.fork()

Creates a new worker process. Calling this method returns a worker object.

cluster.isMaster

If it is the master process, then it istrue。

cluster.isWorker

If it is a worker process, then it istrue。

cluster.workers

A hash table containing all active worker objects, withworker.idas the key name.


Practical application scenarios

1. Load balancing

Example

// In the master process
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  require('./app'); // Your application entry file
}

2. Graceful restart

Example

cluster.on('exit', (worker, code, signal) => {
  console.log(`Worker ${worker.process.pid}exited`);
  // You can fork a new worker here
  cluster.fork();
});

3. Inter-process communication

Example

// The master process sends a message
worker.send('Hello worker!');

// The worker receives the message
process.on('message', (msg) => {
  console.log(`Worker ${process.pid}Received message: ${msg}`);
});

Performance optimization tips

  1. Create workers based on the number of CPU cores: It is usually recommended that the number of workers equals the number of CPU cores.

  2. Shared port: All workers share the same port, and the operating system automatically distributes requests to different workers.

  3. Shared connections: For long-lived connections (such as WebSocket), you need to consider how connections are distributed to different workers.

  4. Shared state: Workers do not share memory, so you need to use external storage such as Redis to share state.


Common problems and solutions

1. Memory leak

Each worker is an independent process. A memory leak in one worker will not affect other workers, but you need to monitor and restart abnormal workers.

2. Session persistence

If session persistence is needed, you can use sticky sessions or store session data externally (e.g., Redis).

3. File descriptor limit

A large number of workers may exhaust file descriptors, so you need to adjust system limits:

Example

ulimit -n 10000  # Set file descriptor limit

Alternatives to the Cluster module

AlthoughclusterThe module is powerful, but there are other options:

  1. PM2: Process manager with built-in load balancing and monitoring features
  2. Nginx: A reverse proxy that can load balance across multiple Node.js instances
  3. Kubernete: A container orchestration system that can automatically scale Node.js services

Summary

Node.js'sclustermodule is an important tool for building high-performance, highly available network services. By creating multiple worker processes, we can:

  1. Fully utilize the performance of multi-core CPUs
  2. Improve application reliability
  3. Achieve zero-downtime deployment

Although setting up and managing multi-process applications is more complex than single-process, for production Node.js applications, usingclusterThe module or similar solutions is almost essential.

Hope this guide helps you understand and use Node.js'sclustermodule!

Java FileNode.js built-in modules

Other extensions