我是nodejs新手,目前正在学习。 我知道nodejs是单线程的,但是我想知道:如果我使用非阻塞方法, 比如有20000个并发请求,有一个请求需要较长时间,其他线程需要较短时间。
那么一旦遇到时间较长的请求,nodejs就会说“嗨,请暂停,其他请求需要使用”,nodejs是否有一个默认的时间来检测是否需要暂停?如果我使用了错误的单词“puase”,请纠正我(因为我认为由于它是单线程,所以如果要处理另一个请求,它应该停止计算一个请求)。
在我假设的情况下,那么较长的请求需要很多时间才能处理?
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。
我也遇到了同样的问题,可以使用集群,一定程度上可以解决问题。这是演示代码:
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`);
}