Nodejs-cluster module knowledge points summary and example usage

Nodejs-cluster module knowledge points summary and example usage

The interviewer will sometimes ask you, tell me how to start multiple processes in NodeJS. The cluster module should immediately appear in your mind. Now let me take you to explore the use of the cluster module.

Basic Usage

Node.js runs as a single process by default, and can use up to 512MB of memory for 32-bit systems and up to 1GB of memory for 64-bit systems. For computers with multi-core CPUs, this is very inefficient because only one core is running and the other cores are idle. The cluster module is proposed to solve this problem.

The cluster module allows you to set up a master process and several worker processes, with the master process monitoring and coordinating the operation of the worker processes. Workers use inter-process communication to exchange messages. The cluster module has a built-in load balancer that uses the Round-robin algorithm to coordinate the load between worker processes. During operation, all newly established links are completed by the main process, and then the main process assigns the TCP connection to the specified worker process.

var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster){
for (var i = 0, n = os.cpus().length; i < n; i += 1){
cluster.fork();
}
} else {
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}

The above code first determines whether the current process is the master process (cluster.isMaster). If so, it creates several worker processes according to the number of CPU cores. If not, it means that the current process is a worker process, and a server program is started in the process.

The above code has a disadvantage that once the worker process hangs, the main process cannot know it. To solve this problem, you can deploy listening functions for online events and exit events in the main process.

var cluster = require('cluster');
 
if(cluster.isMaster) {
  var numWorkers = require('os').cpus().length;
  console.log('Master cluster setting up ' + numWorkers + ' workers...');
 
  for(var i = 0; i < numWorkers; i++) {
    cluster.fork();
  }
 
  cluster.on('online', function(worker) {
    console.log('Worker ' + worker.process.pid + ' is online');
  });
 
  cluster.on('exit', function(worker, code, signal) {
    console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
    console.log('Starting a new worker');
    cluster.fork();
  });
}

In the above code, once the main process monitors the exit event of the worker process, it will restart a worker process. Once the worker process is started successfully and can run normally, it will emit an online event.

Worker Object

The worker object is the return value of cluster.fork() and represents a worker process.

Its properties and methods are as follows.

(1) worker.id

worker.id returns the unique process ID of the current worker. This number is also the index value pointing to the current process in cluster.workers.

(2) worker.process

All worker processes are spawned using child_process.fork(). The object returned by child_process.fork() is stored in worker.process. Through this property, you can get the process object where the worker is located.

(3) worker.send()

This method is used to send information to the child process in the main process.

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');
} else if (cluster.isWorker) {
  process.on('message', function(msg) {
    process.send(msg);
  });
}

The purpose of the above code is that the worker process echoes every message sent by the main process.

In the worker process, to send a message to the main process, use process.send(message); to listen to the messages sent by the main process, use the following code.

process.on('message', function(message) {
  console.log(message);
});

The message sent can be a string or a JSON object. Below is an example of sending a JSON object.

worker.send({
  type: 'task 1',
  from: 'master',
  data: {
    // the data that you want to transfer
  }
});

cluster.workers Object

This object is only available in the main process and includes all worker processes. The key value of each member is a worker process object, and the key name is the worker.id attribute of the worker process.

socket.on('data', function(id) {
  var worker = cluster.workers[id];
});

Properties and methods of the cluster module

isMaster,isWorker

The isMaster property returns a Boolean value indicating whether the current process is the master process. This property is determined by process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined, it means that the process is the main process.

The isWorker property returns a Boolean value indicating whether the current process is a worker process. It is the opposite of the value of the isMaster property.

fork()

The fork method is used to create a new worker process, and the context is copied to the main process. Only the main process can call this method.

This method returns a worker object.

kill()

The kill method is used to terminate the worker process. It can accept a single parameter, representing the system signal.

If the current process is the main process, it will terminate the connection with worker.process and then send the system signal method to the worker process. If the current process is a worker process, it will terminate the communication with the main process, then exit and return 0.

In previous versions, this method was also called worker.destroy().

Listening Event

After the worker process calls the listening method, the "listening" event is transmitted to the server of the process and then to the main process.

The callback function of this event accepts two parameters, one is the current worker object, and the other is the address object, which contains information such as the URL, port, address type (IPv4, IPv6, Unix socket, UDP), etc. This is useful for Node applications that serve multiple URLs.

Restart Node service without interruption

To restart the service, you need to shut it down and then start it again. Using the cluster module, you can start a worker process first and then shut down all the original worker processes. This will allow you to restart the Node service without interruption.

First, the master process sends a restart signal to the worker process.

workers[wid].send({type: 'shutdown', from: 'master'});

The worker process listens to the message event and exits once it finds that the content is shutdown.

process.on('message', function(message) {
  if(message.type === 'shutdown') {
    process.exit(0);
  }
});

Below is a function that shuts down all worker processes.

function restartWorkers() {
  var wid, workerIds = [];
  for(wid in cluster.workers) {
    workerIds.push(wid);
  }
 
  workerIds.forEach(function(wid) {
    cluster.workers[wid].send({
      text: 'shutdown',
      from: 'master'
     });
    setTimeout(function() {
      if (cluster.workers[wid]) {
        cluster.workers[wid].kill('SIGKILL');
      }
    }, 5000);
  });
};

PM2 Modules

The PM2 module is a wrapper around the cluster module. Its function is to abstract the cluster module as much as possible, allowing users to deploy multi-process Node applications as if they were using a single process.

// app.js
var http = require('http');
 
http.createServer(function(req, res) {
  res.writeHead(200);
  res.end("hello world");
}).listen(8080);

Run this code from the command line using PM2

$ pm2 start app.js -i 4

The i parameter in the above code tells PM2 that this code should be started in cluster_mode and the number of new worker processes is 4. If the value of the i parameter is 0, PM2 will start several worker processes depending on how many CPU cores the current machine has.

If a worker process dies for some reason, it will be restarted immediately.

# Restart all worker processes $ pm2 reload all

Each worker process has an id. You can use the following command to view the details of a single worker process.

$ pm2 show <worker id>

When shutting down the worker process, you can deploy the following code to let the worker process listen to the shutdown message. Once you receive this message, complete the final cleanup work and close it

process.on('message', function(msg) {
  if (msg === 'shutdown') {
    close_all_connections();
    delete_logs();
    server.close();
    process.exit(0);
  }
});

This is the end of this article about the summary of Nodejs-cluster module knowledge points and example usage. For more information about Nodejs-cluster module, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

<<:  Statement to determine browser version and compatible with multiple browsers

>>:  An example of how to implement an adaptive square using CSS

Recommend

Implementation of running springboot project with Docker

Introduction: The configuration of Docker running...

Front-end development must learn to understand HTML tags every day (1)

2.1 Semanticization makes your web pages better u...

The difference between Vue interpolation expression and v-text directive

Table of contents 1. Use plugin expressions 2. Us...

Click the toggle button in Vue to enable the button and then disable it

The implementation method is divided into three s...

How to remotely connect to MySQL database with Navicat Premium

The party that creates a new connection is equiva...

Summary of the Differences between find() and filter() Methods in JavaScript

Table of contents Preface JavaScript find() Metho...

Web page custom selection box Select

Everyone may be familiar with the select drop-dow...

Specific use of MySQL internal temporary tables

Table of contents UNION Table initialization Exec...

How to implement Hover drop-down menu with CSS

As usual, today I will talk about a very practica...

Linux C log output code template sample code

Preface This article mainly introduces the releva...

jQuery implements breathing carousel

This article shares the specific code of jQuery t...

The most complete package.json analysis

Table of contents 1. Overview 2. Name field 3. Ve...