node.js - 生成 1000 多张图像导致负载过重

node.js - generating 1000s of images causing heavy load

我是 node.js 的新手。 我想通过 imagick、gmagick 生成一些图像用于测试目的。 图片的名称应从 000001.jpg 到 0x.jpg。 对于以后的测试,我需要大约 50.000 张图像。

var async = require('async');
var gm = require('gm')
            .subClass({ imageMagick: true }); // Enable ImageMagick integration.


var number = parseInt(process.argv[2]) || 20;
console.log("Generating " + number + " images");

var pad = "000000";
var img_names = [];
for (i=1;i<=number;i++) {
    var str = "" + i;
    var padded_str = pad.substring(0, pad.length - str.length) + str;
    img_names.push(padded_str+".jpg");
}

async.forEach(img_names, function (item, callback){ 
    console.log(item); // print the key
    gm(800, 600, "#ddff99f3").font("Helvetica.ttf", 80)
    .drawText(150, 300, "# "+item)
    .write("./"+item, function (err) {
      if(err) {
        console.error(err);
        process.exit(1);
      }
    }); 
    callback(); // tell async that the iterator has completed

}, function(err) {
    console.log('iterating done');
});

问题是,当使用大量图像时,ubuntu 机器会启动大量 "convert" 进程并进入繁重的负载。

谁能指出我正确的方向? 亲切的问候,罗伯特

您需要将 callback() 函数移动到写入函数的回调中,因为迭代刚刚分叉 gmagick,实际上并没有等待它完成。当它完成时,它会调用自己的回调 - 这是迭代的结束,因此应该调用 forEach() 函数的回调。

如上移动 callback() 将阻塞 async.forEach() 直到 gm() 函数完成。

如果您有一台多核机器,您可以 运行 并行执行此功能,每个 core/hyperthread 大约一个工作进程是一个合理的默认值。将 forEach 换成 eachLimit() 并将并行度设置为 8:

async.eachLimit(img_names, 8, function (item, callback){ 
    console.log(item); // print the key
    gm(800, 600, "#ddff99f3").font("Helvetica.ttf", 80)
    .drawText(150, 300, "# "+item)
    .write("./"+item, function (err) {
      if(err) {
        console.error(err);
        process.exit(1);
      }
      callback(); // tell async that the iterator has completed
    }); 

}, function(err) {
    console.log('iterating done');
});