📜  如何使用 Node.js 运行多个并行 HTTP 请求?

📅  最后修改于: 2022-05-13 01:56:29.622000             🧑  作者: Mango

如何使用 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 操作。
  • 产卵工人并不便宜。