A brief discussion on creating cluster in nodejs

A brief discussion on creating cluster in nodejs

cluster

We know that the event loop or event response processor of nodejs is single-threaded, but nowadays CPUs are basically multi-core. In order to make full use of the multi-core characteristics of modern CPUs, we can create a cluster so that multiple child processes can share the same server port.

That is to say, through cluster, we can use multiple child processes to serve requests for the same port.

Let's take a look at a simple example of using cluster in an http server:

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

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

  // Spawn a worker process.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker process ${worker.process.pid} has exited`);
  });
} else {
  // Worker processes can share any TCP connection.
  // In this example, the HTTP server is shared.
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello World\n');
  }).listen(8000);

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

Cluster Details

The cluster module is derived from lib/cluster.js. We can use cluster.fork() to create a child worker process to handle requests from the main process.

Events in a cluster

Cluster inherits from events.EventEmitter, so cluster can send and receive events.

The cluster supports 7 events: disconnect, exit, fork, listening, message, online and setup.

Before explaining disconnect, let us first introduce a concept called IPC. The full name of IPC is Inter-Process Communication, which means inter-process communication.

IPC is mainly used for communication between the main process and the subprocess. A worker process automatically connects to its master process after it is created. The connection will be disconnected when the 'disconnect' event is emitted.

There are many reasons for triggering the disconnect event, which can be an active call to worker.disconnect() or the worker process exiting or being killed.

cluster.on('disconnect', (worker) => {
  console.log(`Worker process #${worker.id} has disconnected`);
});

The exit event is triggered when any worker process is closed. It is generally used to monitor whether a process in the cluster exits abnormally. If it exits, use cluster.fork to create a new process to ensure that there are enough processes to handle requests.

cluster.on('exit', (worker, code, signal) => {
  console.log('Working process %d closed (%s). Restarting...',
              worker.process.pid, signal || code);
  cluster.fork();
});

The fork event is triggered when the cluster.fork method is called.

const timeouts = [];
function errorMsg() {
  console.error('Connection error');
}

cluster.on('fork', (worker) => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});

The listening events of the main process and the worker process will be triggered when the worker process calls the listen method.

cluster.on('listening', (worker, address) => {
  console.log(
    `Worker process connected to ${address.address}:${address.port}`);
});

Worker represents the working thread, and address contains three attributes: address, port and addressType. The addressType has four optional values:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (Unix domain socket)
  • 'udp4' or 'udp6' (UDP v4 or v6)

The message event is triggered when the main process receives a message sent by the child process.

When the main process generates a worker process, fork is triggered, and when the worker process runs, online is triggered.

When the setupMaster method is called, the setup event is triggered.

Methods in cluster

There are three methods in cluster, namely disconnect, fork and setupMaster.

cluster.disconnect([callback])

Calling the disconnect method of the cluster actually calls the disconnect method in each worker in the cluster. This disconnects the worker from the main process.

When all workers are disconnected, the callback will be executed.

cluster.fork([env])

The fork method creates a new child process from the main process. Where env is the key-value pair to be added to the process environment variables.

fork will return a cluster.Worker object representing the worker process.

The last method is setupMaster:

cluster.setupMaster([settings])

By default, cluster creates child processes through the fork method, but we can change this behavior through setupMaster. By setting the settings variable, we can change the behavior of the subsequent fork child process.

Let's look at an example of setupMaster:

const cluster = require('cluster');
cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true
});
cluster.fork(); // https worker process cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'http']
});
cluster.fork(); // http worker process

Attributes in cluster

Through the cluster object, we can use isMaster and isWorker to determine whether the process is the main process.

You can get a reference to the current worker process object through worker:

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('This is the main process');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`This is the worker process#${cluster.worker.id}`);
}

You can traverse the active worker process objects through workers:

// Iterate over all worker processes.
function eachWorker(callback) {
  for (const id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker((worker) => {
  worker.send('notify all worker processes');
});

Each worker has an id number, which is used to locate the worker.

Workers in a cluster

The worker class contains all the common information and methods about the worker process. What cluster.fork produces is the worker object.

Worker events are very similar to cluster events, supporting 6 events: disconnect, error, exit, listening, message, and online.

The worker contains three properties: id, process and exitedAfterDisconnect.

The id is the unique identifier of the worker.

The process in the worker is actually a ChildProcess object, which is created through child_process.fork().

Because process is a global variable in the worker, we can use process directly in the worker to send messages.

exitedAfterDisconnect means that if the worker process exits due to .kill() or .disconnect(), the value is true. If the exit is by other means, the return value is false. Undefined if the worker process has not yet exited.

We can use worker.exitedAfterDisconnect to distinguish whether it is an active exit or a passive exit. The main process can decide whether to regenerate the worker process based on this value.

cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('This is a spontaneous exit, no need to worry');
  }
});

// Kill the worker process.
worker.kill();

The worker also supports 6 methods: send, kill, destroy, disconnect, isConnected, and isDead.

Here we mainly explain the send method to send messages:

worker.send(message[, sendHandle[, options]][, callback])

You can see that the send method and the send method parameters in child_process are actually very similar. Essentially, worker.send is in the master process, which sends a message to a specific worker process. Equivalent to ChildProcess.send(). In the worker process, this sends a message to the master process. Equivalent to process.send().

if (cluster.isMaster) {
  const worker = cluster.fork();
  worker.send('hello');

} else if (cluster.isWorker) {
  process.on('message', (msg) => {
    process.send(msg);
  });
}

In the above example, if we are in the main process, we can use worker.send to send messages. In the child process, you can use the global variable process in the worker to send messages.

Summarize

Using cluster can fully utilize the advantages of multi-core CPU. I hope you can apply it in actual projects.

The above is a brief discussion of the details of creating a cluster in nodejs. For more information about creating a cluster in nodejs, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • How to share data among multiple processes in cluster module in Nodejs
  • Redis Cluster data sharding mechanism principle
  • Redis Cluster Graphics
  • Introduction to Redis cluster
  • In-depth interpretation of the cluster module in Node.js
  • A brief discussion on clusters in nodes
  • Tutorial on using cluster in node.js
  • Node.js uses cluster to implement multi-process

<<:  Analysis of how to create a stored procedure in MySQL to add new fields to a data table

>>:  Diagram of the Hyperledger Fabric 1.4 environment construction process under Windows 10

Recommend

Quickly solve the problem that the mysql57 service suddenly disappeared

one, G:\MySQL\MySQL Server 5.7\bin> mysqld --i...

Common considerations for building a Hadoop 3.2.0 cluster

One port changes In version 3.2.0, the namenode p...

XHTML Tutorial: XHTML Basics for Beginners

<br />This site’s original content, please i...

Native js to implement drop-down menu

Drop-down menus are also very common in real life...

js to realize web music player

This article shares simple HTML and music player ...

iFrame is a great way to use it as a popup layer to cover the background

I have been working on a project recently - Budou ...

Implementation of form submission in html

Form submission code 1. Source code analysis <...

How to use ECharts in WeChat Mini Programs using uniapp

Today, we use uniapp to integrate Echarts to disp...

How to define data examples in Vue

Preface In the development process, defining vari...

Mysql accidental deletion of data solution and kill statement principle

mysql accidentally deleted data Using the delete ...

XHTML Getting Started Tutorial: Form Tags

<br />Forms are an important channel for use...

How to use Maxwell to synchronize MySQL data in real time

Table of contents About Maxwell Configuration and...