Multithreading 如何在NodeJS中执行图像处理?
我正在NodeJS上编写一个图像处理web服务,在basic中,我需要弄清楚如何使实际的图像处理线程化。当我通过ApacheAb测试它时,NodeJS只使用了一个内核,并且出现了停滞,我肯定在这里做了一些错误的事情。我如何重新设计这个简单的应用程序,以利用我的服务器CPU上的多个核心 我缩小了所有输入过滤,简化了图像处理功能,让您了解应用程序的结构,而不是长代码位 在app.js中Multithreading 如何在NodeJS中执行图像处理?,multithreading,node.js,image-processing,asynchronous,express,Multithreading,Node.js,Image Processing,Asynchronous,Express,我正在NodeJS上编写一个图像处理web服务,在basic中,我需要弄清楚如何使实际的图像处理线程化。当我通过ApacheAb测试它时,NodeJS只使用了一个内核,并且出现了停滞,我肯定在这里做了一些错误的事情。我如何重新设计这个简单的应用程序,以利用我的服务器CPU上的多个核心 我缩小了所有输入过滤,简化了图像处理功能,让您了解应用程序的结构,而不是长代码位 在app.js中 app.get('/generate/:q', function(req, res){ var textS
app.get('/generate/:q', function(req, res){
var textString = req.params.q;
res.setHeader("Content-Type", "image/png");
res.end(generator.s());
});
var Canvas = require('canvas')
, Font = Canvas.Font
, fs = require('fs')
, path = require("path")
, plate = new Canvas.Image;
//To keep plate in RAM between requests.
fs.readFile(__dirname + '/plates/dhw132.png', function(err, squid){
if (err) throw err;
plate.src = squid;
});
exports.s = function () {
canvas = new Canvas(731,1024);
ctx = canvas.getContext('2d');
ctx.drawImage(plate, 0, 0, plate.width, plate.height);
return canvas.toBuffer();
}
在generate.js中
app.get('/generate/:q', function(req, res){
var textString = req.params.q;
res.setHeader("Content-Type", "image/png");
res.end(generator.s());
});
var Canvas = require('canvas')
, Font = Canvas.Font
, fs = require('fs')
, path = require("path")
, plate = new Canvas.Image;
//To keep plate in RAM between requests.
fs.readFile(__dirname + '/plates/dhw132.png', function(err, squid){
if (err) throw err;
plate.src = squid;
});
exports.s = function () {
canvas = new Canvas(731,1024);
ctx = canvas.getContext('2d');
ctx.drawImage(plate, 0, 0, plate.width, plate.height);
return canvas.toBuffer();
}
如何重写它以使generator.s()线程化?节点当然是单线程的,但是需要多线程是一个非常有效的用例。我知道有两种方法 为什么不使用集群呢。您将获得一个可配置的进程/线程数,默认情况下是您机器上的CPU数。集群本质上是跨进程平衡应用程序的负载,并透明地处理共享单个侦听http端口的进程 这里也有一个包装: 另一种选择是,您可以直接分叉该过程,下面是一个使用lame将上载的文件转换为mp3的示例。。对于您的情况,您可以将所有图像处理封装在一个单独的应用程序中,因此集群选项可能会更干净
app.post('/process', function(req, res){
var f = req.files.filen;
fs.rename(f.path, f.name, function(err) {
if (err){
fs.unlink(f.name, ef);
throw err;
return;
}
fs.unlink(f.path, function() {
var ext = "." + req.body.extn;
require('child_process').exec("lame "+f.name, function(err, out, er) {
var nfn = f.name + '.mp3';
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-disposition', 'attachment; filename='+nfn);
res.setHeader("Content-Transfer-Encoding: binary");
res.setHeader('Accept-Ranges: bytes');
var size = fs.statSync(nfn).size;
console.log(size, f.name, nfn)
res.setHeader('Content-Length', size);
fs.createReadStream(nfn).pipe(res);
fs.unlink(nfn, ef); fs.unlink(f.name, ef);
})
})
})
})
Node.js是单线程的。在NodeJs中没有一种简单的方法可以做到这一点。是的,我意识到这是因为Node处理请求的方式,但我仍然不能简单地用不同的核心来实现这个可执行文件,我读过关于子进程分叉的内容,但似乎没有简单的方法将实际的板读入内存一次,然后将canvas函数生成到一个进程中,该进程在另一个线程中引用文件执行。只有一个线程。最简单的方法是在每个进程中加载图像。正如您所看到的,数据处理不一定非常适合NodeJ。它最适用于小型异步任务。我们将尝试使用它和基准测试,目前看起来是这样的。当然,在可能的情况下,一定要使用异步文件操作。