1

我在NodeJS上編寫圖像處理Web服務,在基本上我需要弄清楚如何使實際的圖像處理線程化。當我通過Apache AB進行測試時,NodeJS只使用一個內核並停止運行,我確實在這裏做了一些錯誤。我如何重新設計這個簡單的應用程序,以利用我的服務器CPU上的多個核心。我如何在NodeJS中進行圖像處理?

我縮小了所有輸入過濾條件,簡化了圖像處理功能,讓您瞭解應用程序結構而不是長碼位。

在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

Node.js是單線程的。在NodeJs中沒有簡單的方法來完成它。 http://stackoverflow.com/questions/10773564/which-would-be-better-for-concurrent-tasks-on-node-js-fibers-web-workers-or-t – WiredPrairie

+0

是的,我意識到這是由於方式節點處理請求,但我仍然無法繞過一個簡單的方法在不同的內核中創建這個可執行文件,我閱讀了Child Process forking,但似乎沒有簡單的方法將實際的平板讀入內存,然後產生canvas函數放入一個進程中,該進程通過引用另一個線程中的文件來執行。 – saxly

+0

只有一個線程。最簡單的方法就是在每個進程中加載​​圖像。正如你所看到的,數據處理並不一定非常適合NodeJ。它適用於小型異步任務。 – WiredPrairie

回答

2

節點當然是單線程,但是對多線程的需求是非常有效的用例。有兩種方式我知道。

爲什麼不使用羣集。您將獲得可配置數量的進程/線程,默認情況下爲您機器上的cpus數量。集羣本質上是跨進程負載均衡您的應用程序,並透明地處理那些共享單個監聽http端口的進程。

http://nodejs.org/api/cluster.html

有它的包裝,以及在這裏:​​

不同的選項,你可以直接用叉子叉過程,這裏的地方上傳的文件被使用跛腳轉換爲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); 
        }) 
      }) 
     }) 
}) 
相關問題