我正在NodeJS上编写一个图像处理Web服务,基本上我需要弄清楚如何使实际的图像处理成为线程。当我通过Apache AB测试NodeJS只使用一个核心并停止时,我肯定在这里做错了。我如何重新设计这个简单的应用程序,以利用我的服务器CPU上的多个核心。
我缩小了所有输入过滤并简化了图像处理功能,让您了解应用程序结构而不是长代码位。
在app.js
app.get('/generate/:q', function(req, res){
var textString = req.params.q;
res.setHeader("Content-Type", "image/png");
res.end(generator.s());
});
在generate.js
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()线程化?
答案 0 :(得分:2)
Node当然是单线程,但需要多线程是一个非常有效的用例。我知道有两种方式。
为什么不使用群集。您将获得可配置数量的进程/线程,默认情况下是您计算机上的cpu数量。集群实质上是跨进程对应用程序进行负载均衡,并透明地处理共享单个侦听http端口的进程。
http://nodejs.org/api/cluster.html
这里有一个包装器:https://github.com/dpweb/cluster-node
一个不同的选项,你可以直接分叉这个过程,这里是一个使用lame将上传的文件转换为mp3的例子。对于你的情况,你将所有的图像处理封装在一个单独的应用程序中,所以cluster选项可能做得那么干净。
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);
})
})
})
})