node.js http.get在对远程站点的5个请求后挂起

sca*_*ald 32 http node.js express

我正在编写一个简单的api端点来确定我的服务器是否能够访问互联网.它运行良好,但在5个请求(每次正好5个)之后,请求挂起.当我将Google切换到Hotmail.com时会发生同样的事情,这让我认为这是我的最终目的.我需要关闭http.get请求吗?我的印象是这个函数会自动关闭请求.

// probably a poor assumption, but if Google is unreachable its generally safe to say     that the server can't access the internet
// using this client side in the dashboard to enable/disable internet resources

app.get('/api/internetcheck', function(req, res) {
console.log("trying google...");
    http.get("http://www.google.com", function(r){
        console.log("Got status code!: " +r.statusCode.toString());
        res.send(r.statusCode.toString());
        res.end();
        console.log("ended!"); 
    }).on('error', function(e) {
        console.log("Got error: " + e.message);
    });
});
Run Code Online (Sandbox Code Playgroud)

rob*_*lep 52

这就是"确切5"的原因:https://nodejs.org/docs/v0.10.36/api/http.html#http_agent_maxsockets

在内部,http模块使用代理类来管理HTTP请求.默认情况下,该代理将允许最多5个到同一HTTP服务器的打开连接.

在您的代码中,您不会使用Google发送的实际响应.因此,代理假定您没有完成请求,并将保持连接打开.因此,在5次请求之后,代理将不再允许您创建新连接,并将开始等待任何现有连接完成.

显而易见的解决方案是只使用数据:

http.get("http://www.google.com", function(r){
  r.on('data', function() { /* do nothing */ });
  ...
});
Run Code Online (Sandbox Code Playgroud)

如果遇到/api/internetcheck大量调用路由的问题,那么您需要允许超过5个并发连接,您可以升级连接池大小,或者只是完全禁用代理(尽管您仍然需要使用两种情况下的数据);

// increase pool size
http.globalAgent.maxSockets = 100;

// disable agent
http.get({ hostname : 'www.google.com', path : '/', agent : false }, ...)
Run Code Online (Sandbox Code Playgroud)

或者也许使用HEAD请求代替GET.

(PS:如果http.get生成错误,您仍应该通过使用res.end()或类似的方式结束HTTP响应).

注意:在Node.js版本> = 0.11中,maxSockets设置为Infinity.

  • 只是为了补充这个优秀的答案 - 我的问题是当我从远程服务器加载PNG blob时,在实例中没有匹配的博客我默认为默认的二进制blob而不是返回404错误.我遇到了这个问题因为我没有消耗加载的数据......非常聪明!如上所述 - 包括r.on('data',function(){/*什么都不做*/}); 并且它欺骗它以为你做并关闭连接! (2认同)