這裏是我的示例代碼:Node.js Http.request在負載測試下變慢。難道我做錯了什麼?
var http = require('http');
var options1 = {
host: 'www.google.com',
port: 80,
path: '/',
method: 'GET'
};
http.createServer(function (req, res) {
var start = new Date();
var myCounter = req.query['myCounter'] || 0;
var isSent = false;
http.request(options1, function(response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
var end = new Date();
console.log(myCounter + ' BODY: ' + chunk + " time: " + (end-start) + " Request start time: " + start.getTime());
if (! isSent) {
isSent = true;
res.writeHead(200, {'Content-Type': 'application/xml'});
res.end(chunk);
}
});
}).end();
}).listen(3013);
console.log('Server running at port 3013');
我發現了什麼是,如果我連接到其他服務器,(谷歌或其他),響應會越來越慢到幾秒鐘。如果我連接到同一網絡中的另一個node.js服務器,則不會發生這種情況。
我使用JMeter進行測試。 1000個循環每秒50個併發。
我不知道是什麼問題...
=========================
進一步調查:
我在Rackspace和EC2上運行相同的腳本進行測試。腳本將使用http.request連接到:Google,Facebook,以及我的另一個腳本,它可以簡單地輸出由另一個EC2實例託管的數據(如hello world)。
測試工具我只是我桌面上的jMeter。
Pre-node.js測試: jMeter - > Google結果:快速且一致。 jMeter - > Facebook的結果:快速和一致。 jMeter - >我的簡單輸出腳本結果:快速和一致。
然後,我製作了50個並行線程/秒,帶有100個循環,測試了我的Rackspace nodejs,然後EC2 node.js,它具有相同的性能問題 jMeter - > node.js - > Google結果:在200個需求中從50毫秒變爲2000毫秒。
jMeter - > node.js - > Facebook結果:從200 ms到200 ms後需要3000 ms。
jMeter - > node.js - >我的簡單輸出腳本結果:在200個請求之後,從100 ms到1000 ms。
前10-20個請求很快,然後開始放慢速度。
然後,當我更改爲10個併發線程時,事情開始發生變化。響應非常一致,沒有減慢。
與Node.js(http.request)可以處理的併發線程數量有關。
------------ 更 --------------
今天我做了更多的測試,在這裏,它是: 我用http.Agent並增加最大套接字。然而,有趣的是,在一臺測試服務器(EC2)上,它提高了很多,並且沒有更慢的速度。 HOwever,其他服務器(機架空間)只有一點改進。它仍然顯示出放緩。我甚至在請求標題中設置了「Connection:close」,它只提高了100ms。
如果http.request使用連接池,如何增加它?
在這兩個服務器,如果我做 「的ulimit -a」,打開文件的#1024
------------- ** 更多更多 * * -------------------
看來,即使我把maxSockets設置爲更高的數字,它只能在一定的限制。似乎有一個內部或OS依賴的套接字限制。但是要碰撞它?
------------- **經過廣泛的測試** ---------------
閱讀大量帖子後,我發現:
轉引自:https://github.com/joyent/node/issues/877
1)如果我設置的標頭與連接= '保活',表現還是不錯的,可以上去到maxSocket = 1024(這是我的Linux設置)。
var options1 = {
host: 'www.google.com',
port: 80,
path: '/',
method: 'GET',
**headers: {
'Connection':'keep-alive'
}**
};
如果我將它設置爲「連接」:「關閉」,響應時間會慢100倍。
有趣的事情發生在這裏:
在EC2 1),當我第一次測試與連接:保持活躍,這將需要大約20-30毫秒。然後,如果我更改爲連接:關閉或設置代理:false,響應時間將減慢到300毫秒。 WIHTOUT重新啓動服務器,如果我更改爲Connection:再次保持活動狀態,則響應時間將進一步減慢到4000毫秒。要麼我必須重新啓動服務器或等待一段時間才能恢復20-30ms的照明速度響應。 2)如果我使用agent運行它:false,首先,響應時間將減慢到300ms。但是,它會再次變得更快,並回到「正常」。
我的猜測是連接池仍然有效,即使你設置了agent:false。但是,如果您保持連接:保持連接,那麼它肯定會很快。只是不要切換它。
7月25日更新,2011
我試圖與http.js & https.js最新的node.js V0.4.9從https://github.com/mikeal/node/tree/http2
的修復性能更好更穩定。
而不是做'isSent'魔法,你應該監聽response.on('end')'事件。 – 2011-06-02 00:30:44
感謝您的建議。 :) – murvinlai 2011-06-04 01:13:09
我遇到同樣的問題,並看到保持活着的變化相當大的性能增益,但是在負載測試後的一段時間我遇到了錯誤。 下面是錯誤: {[錯誤:連接EADDRNOTAVAIL] 代碼: 'EADDRNOTAVAIL', 錯誤號: 'EADDRNOTAVAIL', 系統調用: '連接'} – firemonkey 2013-04-30 15:16:03