考虑以下简单的Node.js应用程序:
var http = require('http');
http.createServer(function() { }).listen(8124); // Prevent process shutting down
var requestNo = 1;
var maxRequests = 2000;
function requestTest() {
http.request({ host: 'www.google.com', method: 'GET' }, function(res) {
console.log('Completed ' + (requestNo++));
if (requestNo <= maxRequests) {
requestTest();
}
}).end();
}
requestTest();
它一个接一个地向谷歌发出2000个HTTP请求。问题是,它收到5号请求并暂停约3分钟,然后继续处理6-10号请求,然后再暂停3分钟,再请求11-15,暂停,依此类推。
编辑:
我试着将www.google.com更改为localhost,这是一个运行我的机器的非常基本的Node.js应用程序,它会返回“Hello world”,但我仍然有3分钟的暂停时间。
现在我读到我可以增加连接池限制:
http.globalAgent.maxSockets = 20;
现在,如果我运行它,它会处理1-20个请求,然后暂停3分钟,然后处理21-40个请求,再暂停,以此类推。
最后,经过一点研究,我了解到可以通过设置完全禁用连接池
agent: false
在请求选项中:
http.request({ host: 'www.google.com', method: 'GET', agent: false }, function(res) {
...snip....
……它会很好地处理所有2000个请求。
我的问题是,这样做是个好主意吗?是否有可能导致HTTP连接过多?为什么它会暂停3分钟,当然,如果我已经完成了连接,它应该直接将它添加回池中,为下一个使用请求做好准备,那么它为什么要等待3分钟呢?原谅我的无知。
如果做不到这一点,Node.js应用程序在不锁定或崩溃的情况下发出潜在的大量HTTP请求的最佳策略是什么?
我在Mac OSX 10.8.2上运行Node.js版本0.10。
编辑:
我发现,如果我将上面的代码转换为for循环,并试图同时建立一组连接,那么在大约242个连接之后,我就会开始出现错误。错误为:
Error was thrown: connect EMFILE
(libuv) Failed to create kqueue (24)
…和代码。。。
for (var i = 1; i <= 2000; i++) {
(function(requestNo) {
var request = http.request({ host: 'www.google.com', method: 'GET', agent: false }, function(res) {
console.log('Completed ' + requestNo);
});
request.on('error', function(e) {
console.log(e.name + ' was thrown: ' + e.message);
});
request.end();
})(i);
}
我不知道一个负载很重的Node.js应用程序是否能同时连接那么多。