gpt4 book ai didi

node.js - 在 NestJS HTTP 服务器中使用子进程时,受 CPU 限制的进程会阻塞工作池

转载 作者:IT老高 更新时间:2023-10-28 23:08:45 28 4
gpt4 key购买 nike

Node 版本: v10.13.0

我正在尝试对涉及大量 CPU 计算的 NodeJS 请求并发进行非常简单的测试。我知道 NodeJS 不是 CPU 密集型进程的最佳工具,不应该系统地生成子进程,但这段代码是为了测试子进程的工作方式。这也是用 TypeScript 编写的,使用 NestJS。

src/app.controller.ts

import { Get, Param, Controller } from '@nestjs/common';
import fork = require('child_process');

@Controller()
export class AppController {
@Get()
async root(): Promise<string> {
let promise = new Promise<string>(
(resolve, reject) => {
// spawn new child process
const process = fork.fork('./src/cpu-intensive.ts');
process.on('message', (message) => {
// when process finished, resolve
resolve( message.result);
});
process.send({});
}
);
return await promise;
}
}

src/cpu-intensive.ts

process.on('message', async (message) => {
// simulates a 10s-long process
let now = new Date().getTime();
let waittime = 10000; // 10 seconds
while (new Date().getTime() < now + waittime) { /* do nothing */ };
// send response to master process
process.send({ result: 'Process ended' });
});

这么长的过程,如果在没有产生新子进程的情况下执行,会导致这个结果时间线,有 5 个并发请求(从 #1 到 #5 注明)。每个进程阻塞循环事件,每个请求都必须等待前一个请求完成才能得到响应。

Time 0    10   20   30   40   50
#1 +----+
#2 +----+----+
#3 +----+----+----+
#4 +----+----+----+----+
#5 +----+----+----+----+----+

在生成新的子进程时,我期望每个进程将由我的 CPU 上的不同逻辑核心同时处理(我的有 8 个逻辑核心),导致这个预测的时间表:

Time 0    10   20   30   40   50
#1 +----+
#2 +----+
#3 +----+
#4 +----+
#5 +----+

虽然,我在每次测试中都观察到了这个奇怪的结果:

Time 0    10   20   30   40   50
#1 +----+
#2 +----+----+
#3 +----+----+----+
#4 +----+----+----++
#5 +----+----+----+-+

前 3 个请求就像工作池被饿死一样,尽管我假设会创建 3 个不同的池。最后的 2 个请求非常令人困惑,因为它们的行为就像与请求 #3 并行工作。

我目前正在寻找以下原因的解释:

  • 为什么前 3 个请求不像同时运行一样运行
  • 为什么最后 3 个请求表现得好像同时运行

请注意,如果我添加另一个“快速”方法如下:

  @Get('fast')
async fast(): Promise<string> {
return 'Fast process ended.';
}

这种方法不受并发运行的 CPU 密集型进程的影响,并且总是立即回复。

最佳答案

我在我的机器上执行了测试用例,它工作正常,你能在你的机器上检查一下吗?

Node Version: v8.11.2 OS: macOs High Sierra 10.13.4, 8 Cores

child-process-test.js

const child_process = require('child_process');  
for(let i=0; i<8; i++) {
console.log('Start Child Process:',i,(new Date()));
let worker_process = child_process.fork("cpu-intensive-child.js", [i]);
worker_process.on('close', function (code) {
console.log('End Child Process:', i , (new Date()), code);
});
}

cpu-intensive-child.js

const fs = require('fs');
// simulates a 10s-long process
let now = new Date().getTime();
let waittime = 10000; // 10 seconds
while (new Date().getTime() < now + waittime) { /* do nothing */ };
// send response to master process
// process.send({ result: 'Process ended' });

输出

enter image description here

您可以检查输出,所有过程的差异只有 10 秒,您可以在您的机器上执行此测试用例并告诉我,可能会有所帮助。

关于node.js - 在 NestJS HTTP 服务器中使用子进程时,受 CPU 限制的进程会阻塞工作池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53399573/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com