如何使用 Node.js 运行多个并行 HTTP 请求?
我们知道 NodeJS 应用程序是单线程的。比如说,如果处理涉及需要 10 秒的请求 A ,这并不意味着该请求之后的请求需要等待 10 秒才能开始处理,因为 NodeJS 事件循环只是单线程的。整个 NodeJS 架构不是单线程的。
NodeJS 如何处理多个客户端请求?
NodeJS 接收多个客户端请求并将它们放入EventQueue中。 NodeJS 是使用事件驱动架构的概念构建的。 NodeJS 有自己的EventLoop ,它是一个接收请求并处理它们的无限循环。 EventLoop 是 EventQueue 的监听器。
如果 NodeJS 可以在没有 I/O 阻塞的情况下处理请求,那么事件循环将自己处理请求并将响应发送回客户端。但是,可以使用 NodeJS集群模块并行处理多个请求 或worker_threads模块。
如何使用集群模块扩展您的 NodeJS 应用程序?
Node.js 的单个实例在单个线程中运行。如果您有一个多核系统,那么您可以利用每个核心。有时开发人员希望启动一个 NodeJS 进程集群以利用多核系统。
集群模块允许轻松创建所有共享相同服务器端口的子进程。
第 1 步:创建一个 NodeJS 应用程序并安装所需的Express.js模块。
mkdir Project && cd Project
npm init -y
npm i express
第 2 步:使用以下代码在根目录上创建一个index.js文件。
Javascript
const express = require('express');
const cluster = require('cluster');
// Check the number of available CPU.
const numCPUs = require('os').cpus().length;
const app = express();
const PORT = 3000;
// For Master process
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// This event is firs when worker died
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
}
// For Worker
else{
// Workers can share any TCP connection
// In this case it is an HTTP server
app.listen(PORT, err =>{
err ?
console.log("Error in server setup") :
console.log(`Worker ${process.pid} started`);
});
}
Javascript
const {Worker} = require('worker_threads');
const worker = new Worker(__filename);
worker.on('message', message => console.log(message));
worker.postMessage('GeeksforGeeks');
worker.emit(true)
说明:如果您的系统有 8 个 CPU,那么将创建 8 个 NodeJS 实例,并且每个实例都有自己独立的事件循环。现在 NodeJS 可以并行处理所有请求。
它们都共享相同的端口(PORT 3000)但没有状态。主进程侦听端口,接受新连接并以循环方式将它们分配给工作进程,并具有一些内置智能以避免工作进程过载。
第 3 步:使用以下命令运行index.js文件。
node index.js
输出:
使用 worker_threads 模块: CPU 性能的最佳解决方案是 Worker Thread。这个模块在 Node.js 中使用,因为它对于执行繁重的 JavaScript 任务很有用。
而不是:
- 一个过程
- 一根线
- 一个事件循环
- 一个 JS 引擎实例
- 一个 Node.js 实例
- 工作线程具有:
一个过程
- 多线程
- 每个线程一个事件循环
- 每个线程一个 JS 引擎实例
- 每个线程一个 Node.js 实例
示例:使用以下代码创建一个index.js文件。
index.js
Javascript
const {Worker} = require('worker_threads');
const worker = new Worker(__filename);
worker.on('message', message => console.log(message));
worker.postMessage('GeeksforGeeks');
worker.emit(true)
使用以下命令运行服务器:
node --experimental-worker index.js
注意:我们必须使用–experimental-worker因为 Workers Thread 模块仍处于试验阶段。
输出:
{ name: ‘GeeksforGeeks’ }
Worker_Threads 的优点:
- 传递本地句柄(http/https 请求)
- 死锁检测。
- 更多的隔离,所以如果一个进程受到影响,它不会影响其他进程。
Worker_Threads 的缺点:
- 不适合 I/O 操作。
- 产卵工人并不便宜。