2016-08-21 50 views
2

我想確定這是否是一個公平的基準。目標是試圖查看有多少併發連接與各種規模的Node.JS可以處理的有效負載。代碼如下。一個簡單的Node.JS基準

var express = require('express'); 
var Sequelize = require('sequelize'); 
var fs = require('fs'); 
var app = express(); 


var data; 

var filename = process.argv[2] || './start.json'; 
console.log("Using: " + filename); 
data = fs.readFileSync(filename); 

var blockSize = 250000; 
app.get('/start', function (req, res) { 
    // Break up data in blocks. Works to super high concurrents. 
    // for(var i = 0; i < data.length; i+=blockSize) 
    // res.write(data.slice(i, i+blockSize)); 

    // Can only handle about 600 concurrent requests if datasize > 500KB 
    res.send(data); 
}); 



app.listen(3000, function() { 
    console.log('Listing on 3000.'); 
}); 

正如評論指出,如果有效載荷大小大於500KB左右大,有500個有它並行註解會得到「通過對等連接復位」在負載測試客戶端。如果您將數據分片並將其分塊寫入,則可以在開始之前保存更高的併發數。股票節點和快遞均顯示此行爲。

+0

問題是大部分數據在RAM中。因此,對於大型有效負載,它歸結爲memcpy()需要多長時間。這正是節點無法很好處理的工作負載。節點針對I/O而不是RAM處理進行了優化。您將獲得更好的併發性,將文件作爲讀取流打開並將其傳輸到客戶端。這樣做會將幾乎所有的負載轉移到操作系統而不是節點上,如果你在Linux或Solaris上,你會從優化的文件系統驅動中獲得巨大的提升。 – slebetman

+0

另一方面,對於小型有效載荷,通常可以獲得更好的性能,將數據保存在RAM中。所以這取決於。 – slebetman

+0

當數據規模較大時,CPU會達到100%,對於節點來說顯然非常糟糕。 –

回答

1
data = fs.readFileSync(filename); 

同步方法是nodejs殺手。它實際上阻止了ALL請求的事件循環,使得演出真的很糟糕。

試試這個:

var express = require('express'); 
var Sequelize = require('sequelize'); 
var fs = require('fs'); 
var app = express(); 
var filename = process.argv[2] || './start.json'; 

var blockSize = 250000; 
app.get('/start', function (req, res) { 
    // Break up data in blocks. Works to super high concurrents. 
    // for(var i = 0; i < data.length; i+=blockSize) 
    // res.write(data.slice(i, i+blockSize)); 

    // Can only handle about 600 concurrent requests if datasize > 500KB 
    console.log("Using: " + filename); 

    fs.readFile(filename, function (err, data) { 
     if (err) throw err; 
     res.send(data); 
    }); 

}); 



app.listen(3000, function() { 
    console.log('Listing on 3000.'); 
}); 
+0

如果您注意到它剛剛在腳本的開始處發生一次。重點不在於對文件的加載進行基準測試 - 僅僅是傳輸。因此,在服務器甚至偵聽連接之前,數據在內存中。 –

0

作爲替代方案,你可以創建一個讀取流和管吧,這裏是例如基於代碼

var express = require('express'); 
var fs = require('fs'); 
var app = express(); 

var data; 

var filename = process.argv[2] || './data.json'; 
console.log("Using: " + filename); 
data = fs.readFileSync(filename); 

var readStream = fs.createReadStream(filename); 

app.get('/start', function (req, res) { 
    // Can only handle about 600 concurrent requests if datasize > 500KB 
    //res.send(data); 
    readStream.pipe(res); 
}); 
+0

這是我的另一個想法。根據它的表現,我願意下注send()在幕後進行。如果你將readStream創建放在/ start中,它就像發送原始流一樣執行。 –

+0

可能是這種情況。我測試了兩個解決方案的結果非常相似。 –

+1

另外,即使更有趣,如果你做了一個大文件(30MB),它甚至比在同一測試中的Go更好。沒有預料到。 –