Введение

Все мы помним, что Node.js по своей природе однопоточен (если не помним, то читаем статью об асинхронности). А что, если нам нужно несколько потоков? К примеру, у нас несколько CPU, и мы хотим использовать всю мощь нашего сервера?

В использовании модуля cluster нет ничего сложного. Проще всего показать это, написав два приложения: одно будет работать в одном потоке, второе — использовать преимущества кластеризации.

Приложение в одном потоке

Напишем простенькое API c использованием Express:

// создадим приложение Express
const app = express();
const port: number = 3000;

// создадим эндпойнт /
app.get('/', (req: Request, res: Response) => {
  res.send('hello world!')
});

// запустим приложение Express на порту port
app.listen(port, () => {
  console.log(`app listening on ${port}`);
});

Оно будет работать, но не будет использовать все наши CPU, если у нас их больше одного. Перепишем это API с использованием модуля cluster.

Приложение в нескольких потоках

import express from 'express';
import cluster from 'cluster';
import os from 'os';
import { Request, Response } from 'express';

// посчитаем количество CPU с помощью модуля os
const totalCPUs = os.cpus().length;

// если мы запускаем кластер
if (cluster.isPrimary) {
  console.log(`number of CPUs is ${totalCPUs}`);
  console.log(`Master ${process.pid} is running`);

  for (let i = 0; i < totalCPUs; i++) {
    cluster.fork(); // форкаем API столько раз, сколько у нас CPU
  }

  // если кластер умрет, запустим еще один
  cluster.on('exit', (worker: Worker, code: number, signal: string ) => {
    console.log(`worker ${process.pid} died`);
    console.log("Let's fork another worker!");
    cluster.fork();
  })
} else { // если запускается воркер
  // создадим приложение Express
  const app = express();
  const port: number = 3000;

  // создадим эндпойнт /
  app.get('/', (req: Request, res: Response) => {
    res.send('hello world!')
  });

  // запустим приложение Express на порту port
  app.listen(port, () => {
    console.log(`app listening on ${port}`);
  });
}

Такое приложение будет использовать все доступные CPU. Таким образом, мы увеличим производительность приложения примерно во столько раз, сколько у нас CPU.

Вывод

А нет вывода :) эта статья — просто пример, как Node.js может использовать несколько потоков.