Node.js 当我启动新的分叉进程时,NodeJS分叉进程正在减慢所有其他分叉进程的速度

Node.js 当我启动新的分叉进程时,NodeJS分叉进程正在减慢所有其他分叉进程的速度,node.js,performance,imagemagick,multiprocessing,fork,Node.js,Performance,Imagemagick,Multiprocessing,Fork,我有一个NodeJS程序,它使用ImageMagick从数据库中的一些文本创建一个图像。该程序从我的NodeJs服务器使用 import childProcess from 'child_process'; let args = [':imageId', '--max_old_space_size=4096']; childProcess.fork('createImage.js', args); 创建映像的过程非常缓慢,在本地计算机上,对于大小为114x84cm的单个映像,可能需要5-6分钟

我有一个
NodeJS
程序,它使用
ImageMagick
从数据库中的一些文本创建一个图像。该程序从我的
NodeJs
服务器使用

import childProcess from 'child_process';
let args = [':imageId', '--max_old_space_size=4096'];
childProcess.fork('createImage.js', args);
创建映像的过程非常缓慢,在本地计算机上,对于大小为114x84cm的单个映像,可能需要5-6分钟

我将尝试解释程序生命周期中发生的事情

所以,我有一个运行在进程
MyServer
上的服务器,当有人请求一个映像
MyServer
时,它会派生一个新进程

新流程
ImageCreator1
有一个来自promises的循环,将等待所有问题得到解决。每个承诺都使用
ImageMagick

在我的活动监视器中,我可以看到一些正在运行的进程

Process Name   |  %CPU
MyServer       -  0.3
ImageCreator1  -  30.0
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1
我还可以看到,
ImageCreator1
运行异步4-5
ImageMagick
转换进程来创建所有这些所需的小图像

这一切需要5分钟。创造大形象

因此,当我启动两个
ImageCreators
时,时间增加到9分钟

Process Name   |  %CPU
MyServer       -  0.3
ImageCreator1  -  30.0
ImageCreator2  -  40.0
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1
convert        -  0.1
convert        -  0.1
convert        -  0.2
convert        -  0.1
如果我开始使用
ImageCreator3
ImageCreator4
会越来越慢。我在想,当我开始一个新的过程,如果这个过程是完成5分钟的工作。然后,如果我同时启动五个过程,每个过程必须完成5分钟。但似乎随着每一个新的
ImageCreator
,所有人的时间都在增加

我仍然在学习
NodeJs
和这个
OS
的东西,所以如果有人能解释发生了什么,那就太好了

!!!更新IMAGECREATOR代码

console.time('imageCreator');
process.title = 'imageCreator'+process.argv[2];

const fs = require('fs');
const gm = require('gm').subClass({imageMagick:true});
const Promise = require('bluebird');

var images = [], rows = [];
for(var i = 1; i<=100;i++){
    images.push(i);
}

for(var i = 1; i<=10;i++){

    rows.push(Promise.reduce(images, function(total, image){

        return new Promise(function(resolve, reject) {

            gm('xc:rgb('+(image*2)+','+image+','+(image*2)+')')
            .in('-units', 'PixelsPerInch')
            .in('-size', '100x100')
            .in('-density', 300)
            .in('-page', '+'+(image-100)*100+'+0')
            .toBuffer('miff', function(err, stream){
                    fs.appendFile(__dirname+'/test'+process.argv[2]+'.miff', stream, function(err){
                        if(err) reject(err);
                        else resolve(image);
                    });
            });

        });

    }));

}


Promise.all(rows).then(function( ) {
    console.timeEnd('imageCreator');
});
因此,当我在一个终端上运行上面的脚本时,我得到如下时间:

Terminal1 - imageCreator: 7498.438ms - 7.4984380002sec.
但当我同时在两个终端上尝试时:

Terminal1 - imageCreator: 14632.522ms - 14.632522sec.
Terminal2 - imageCreator: 13734ms - 13.734sec.
正如你所看到的,这两种方法的时间几乎都增加了一倍

我的电脑有:

processor:2.7 GHz Intel Core i5
memory:8 GB 1867 MHz DDR3

所以发生了什么,我想这里涉及到ram,但我不太擅长这种低级的东西,所以如果有人能解释的话,那就太好了。提前谢谢。

您正在执行此代码的计算机有多少CPU核?当您使用
子进程创建一个新进程时,您正在启动一个新进程——这意味着操作系统调度程序将尝试与父进程并行运行新进程——但这需要多个CPU

如果没有多个CPU,那么操作系统调度程序将开始在运行主进程和子进程之间切换,并在同一个CPU上为每个进程分配CPU时间,从而不会真正“并行”运行它们,因为在任何给定时间只执行一条指令

另一件需要注意的事情是ImageMagick:在多个进程中运行是否安全

我对ImageMagick不太熟悉,但根据2009年的数据(现在可能会有很大不同),ImageMagick使用自己的线程:因此在多个进程中同时运行它不会导致任何加速


希望有帮助

说一幅图像是114cm x 84cm并不能告诉我们太多——在
dpi
为1时,它将是9000像素,但在600dpi时,它将是350000000像素。很抱歉,最后的答案是,图像的
dpi
是300dpi,但这真的有关系吗?比方说,如果我有一个进程运行并转换一个72dpi的图像,当这个进程运行时,我启动另一个进程,这两个进程的时间都会增加。我不知道问题是在ImageMagick还是nodejs中,需要做更多的测试,我将尝试@rdeges共享链接建议编译ImageMagick时使用的方法——禁用openmp,并将模拟我的nodejs程序在没有ImageMagick的情况下运行,并发布结果。谢谢你的评论。我的意思是,114厘米x 84厘米等于45英寸x 33英寸。因此,在300 dpi时,您的图像将具有45*300*33*300像素,即1.33亿像素。如果它是彩色的,有3个通道(RGB)和16位/像素,您需要将其乘以6,因此每个图像至少需要800MB的RAM。也许您应该在
ImageCreator
中显示代码,并查看您的进程上的RAM限制,因为您可能正在向磁盘分页。您好@Mark Setchell,正如您所建议的,我用一些测试代码更新了我的问题,这些代码的行为相同。我正在使用
node test.js 1--max_old_space_size=4096
运行我的节点程序,对于进程来说这是4gb
processor:2.7 GHz Intel Core i5
memory:8 GB 1867 MHz DDR3