Модуль Cluster: как сделать Node.js многопоточным
Введение
Все мы помним, что 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 может использовать несколько потоков.
Интересный пост?
Вот еще похожие:
- Событийно-ориентированная архитектура и Node.js Events
- Реактивное программирование: теория и практика
- Как и зачем писать тесты?
- Функциональное программирование. Что это и зачем?
- Профилирование Node.js-приложений