node.js http.get 在对远程站点发出 5 次请求后挂起

标签 node.js http 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);
    });
});

最佳答案

这是“恰好5”的原因:https://nodejs.org/docs/v0.10.36/api/http.html#http_agent_maxsockets

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

在您的代码中,您不会使用 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 .

关于node.js http.get 在对远程站点发出 5 次请求后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20460693/

相关文章:

javascript - Node.js Http.Request 回调 - 无法将数据传递给父函数

node.js - Nodejs 用户配置文件和 session

javascript - 什么因素可能导致 JS 将位于同一根文件夹中的 iFrame 和子项视为来自不同来源?

java - 如何在服务器端为端口编写重试策略以监听客户端请求?

node.js - 引用错误 : Can't find variable: __fbBatchedBridge

java - 将 webapp 从本地主机移动到服务器 - 找不到页面

node.js - 使用 Meteor (CFS) 下载远程图像

node.js - 在一个应用程序中一起使用 express 和 restify 的 Node js

node.js - express.js - req.body?

javascript - req.getValidationErrors() 不是一个函数