Версия узла: v10.13.0
Я пытаюсь провести очень простой тест на параллелизм запросов NodeJS, связанный с интенсивным вычислением ЦП.Я понимаю, что NodeJS - не лучший инструмент для процессов, связанных с процессором, и что дочерний процесс не должен порождаться систематически , но этот код предназначен для тестирования работы дочерних процессов.Также это написано на 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 -енсивный.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 +----+----+----+----+----+
При порождении новых дочерних процессов я ожидал каждый процесс будет обрабатываться одновременно другим логическим ядром на моем процессоре (у моего есть 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.';
}
этот метод не подвержен влиянию процессов, интенсивно использующих процессор, выполняющихся в параллельном режиме, и всегда отвечает мгновенно.