nodejs单线程?如果有大量并发请求,它如何工作

问题描述 投票:0回答:2

我是nodejs新手,目前正在学习。 我知道nodejs是单线程的,但是我想知道:如果我使用非阻塞方法, 比如有20000个并发请求,有一个请求需要较长时间,其他线程需要较短时间。

那么一旦遇到时间较长的请求,nodejs就会说“嗨,请暂停,其他请求需要使用”,nodejs是否有一个默认的时间来检测是否需要暂停?如果我使用了错误的单词“puase”,请纠正我(因为我认为由于它是单线程,所以如果要处理另一个请求,它应该停止计算一个请求)。

在我假设的情况下,那么较长的请求需要很多时间才能处理?

javascript node.js eventemitter single-threaded
2个回答
11
投票

node.js 确实一次只能接收或响应一个请求,但是,它可以同时处理多个请求。

例如,假设您有一个作为 REST API 的 Node.js 应用程序,每个请求都会导致对数据库的调用(端点 C 除外)。REST API 有 3 个端点。

端点 A:与数据库对话需要 3 秒

端点 B:与数据库对话需要 2 秒

端点 C:不与数据库对话,仅返回静态文本。

不可能同时发生超过 1 个请求。无论时间戳有多接近,一个总是第一个。

现在,假设我们同时发生 10 个请求,按以下顺序:

ABCBCCAABC

以下是他们的接收和回复方式:

REC:A
REC:B
REC:C
RESP:C
REC:B
REC:C
RESP:C
REC:C
RESP:C
REC:A
REC:A
REC:B
REC:C
RESP:C
// 2 seconds later
RESP:B
RESP:B
RESP:B
// 1 second later
RESP:A
RESP:A
RESP:A

C 总是立即发生,因为它不执行任何异步操作。然后您会收到所有 B,然后收到所有 A,因为 B 比 A 快。

B 和 A 的顺序可能会有所不同,具体取决于数据库设置,例如,如果设置为一次仅处理 x 个查询。

如果我们引入端点 D 来执行需要 6 秒的同步操作,您将得到以下结果:

AABC

REQ:A
REQ:D
// 6 long seconds later...
RESP:D
REQ:A
REQ:B
REQ:C
RESP:C
// 2 seconds later...
RESP:B
// 1 second later...
RESP:A
RESP:A

因为 D 在同步操作发生时停止所有 JavaScript 处理。执行同步操作的 1 个端点很容易导致某人停止您的 api。


0
投票

我也遇到了同样的问题,可以使用集群,一定程度上可以解决问题。这是演示代码:

import cluster from 'cluster';
import os from 'os';
import http from 'http';

if (cluster.isPrimary) {
  // Primary process
  const numCPUs = os.cpus().length;
  console.log(`Primary ${process.pid} is running`);

  // Fork workers
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork(); // Restart a new worker if one dies
  });
} else {
  // Worker processes
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello, world!\n');
  }).listen(8000);

  console.log(`Worker ${process.pid} started`);
}
© www.soinside.com 2019 - 2024. All rights reserved.