2014-03-13 22 views
2

我有一個expressJS應用程序,它接受導致執行1k到50K fs.link()動作的請求。 (甚至可能達到500K)。節流CPU NODE.JS動作以允許處理新的調用

當發生這種情況時,請求(POST)沒有被阻止。我立即開始res.send(),這讓客戶感到開心。

但是,服務器然後「分岔」下面的工作,需要去做所有fs.links(),這會發生異步,但工作量(CPU,DISK等)意味着ExpressJS服務在這段時間內對新請求的響應不是很好。

是否有一些簡單的方法(除了childProcess)來模擬將執行這些文件鏈接的低優先級線程的分支?


Job.prototype.runJob = function (next) { 
    var self = this; 
    var max = this.files.length; 
    var count = 0; 
    async.each(this.files, 
     function (file, step) { 
      var src = path.join(self.sourcePath, file.path); 
      var base = path.basename(src); 
      var dest = path.join(self.root, base); 
      fs.link(src, dest, function (err) { 
       if (err) { 
//     logger.addLog('warn', "fs.link failed for file: %s", err.message, { file: src }); 
        self.filesMissingList.push(src); 
        self.errors = true; 
        self.filesMissing++; 
       } else { 
        self.filesFound++; 
       } 
       self.batch.update({ tilesCount: ++count, tilesMax: max, done: false }); 
       step(null); 
      }); 
     }, 
     function (err) { 
      self.batch.update({ tilesCount: count, tilesMax: max, done: true }); 
      next(null, "FalconView Linking of: " + self.type + " run completed"); 
     }); 
} 

回答

1

你可以使用webworker-threads模塊,這是很好的紡CPU密集型任務到其他線程。或者,你可能會濫用cluster,但它確實是這項工作的錯誤工具。 (cluster模塊對於擴展Web服務真的更好,而不是用於執行密集型任務。)

+0

我添加了鏈接任務的代碼示例。 (a)我不確定這是CPU綁定問題還是I/O(理論上鍊接文件似乎更多是I/O問題)。 workther-threads會很有趣,但他們說你需要一個工作節點gyp,並且我一直無法工作幾個月(問題仍然存在)。那簡單的事情呢。例如。每1,000個文件調用一個超時例程,睡眠該節點「線程」,然後再恢復鏈接過程。 –

+0

啊,我明白了。是的,您可能通過在每個文件上調用async.each來濫用。 ('async.eachLimit'可能會有所幫助,但是你仍然會產生大量的事件。)這會讓你的任務比需要的更耗費CPU資源。我建議你通過配置文件來發現調用'fs.link'有多少開銷,而不是一次全部調用,然後嘗試將文件數組分割爲1000個文件塊。您應該能夠避免事件垃圾郵件(因爲500K文件只會產生500個事件),並且仍然讓其他事件在兩者之間運行。 –

+0

我會嘗試async.eachLimit()來查看它是否有幫助。我真正想要做的就是創建一個thread.yield(),以便可以處理新的ExpressJS請求(進度輪詢)。如果這意味着原來的請求被迫停止,或者扼殺到50%就沒問題。只是如何強制「線程」失速。我可以在process.nextTick()插入.each循環,它會有幫助嗎?以及如何把它放進去? –

0

您可以嘗試使用async.eachLimit而不是async.each。通過這種方式,您可以控制在expressJS過程之前處理的迭代次數。