一尘不染

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

node.js

我正在编写一个简单的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);
    });
});

阅读 224

收藏
2020-07-07

共1个答案

一尘不染

这是 “恰好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 */ });
  ...
});

如果您遇到/api/internetcheck路由被调用过多的问题,因此您需要允许5个以上的并发连接,则可以增大连接池的大小,或者完全禁用该代理(尽管您仍然需要消耗两种情况下的数据);

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

// disable agent
http.get({ hostname : 'www.google.com', path : '/', agent : false }, ...)

或使用HEAD请求代替GET

(PS:万一http.get产生错误,您仍应使用res.end()或类似方法结束HTTP响应)。

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

2020-07-07