我正在编写一个简单的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);
});
});
答案 0 :(得分: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 */ });
...
});
如果遇到大量调用/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
。
答案 1 :(得分:3)
如果你等了足够长的时间,5个请求将会超时,接下来的5个请求将会处理,因此应用程序并没有真正挂起,因为它最终将处理所有请求。
要加快处理速度,您需要对响应数据执行某些操作,例如r.on('data', function() {});