问题描述
我正在编写一个简单的 api 端点来确定我的服务器是否能够访问互联网.它工作得很好,但是在 5 个请求(每次正好是 5 个)之后,请求挂起.当我将 Google 切换到 Hotmail.com 时也会发生同样的事情,这让我觉得这是我的结局.我需要关闭 http.get 请求吗?我的印象是这个功能会自动关闭请求.
I'm writing a simple api endpoint to determine if my server is able to reach the internet. It works great, but after 5 requests (exactly 5, every time) the request hangs. Same thing happens when I switch Google to Hotmail.com, which makes me think that this is something on my end. Do I need to close the http.get requests? I was under the impression that this function closes the requests automatically.
// 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 请求.默认情况下,该代理最多允许 5 个打开的连接到同一 HTTP 服务器.
Internally, the http
module uses an agent class to manage HTTP requests. That agent will, by default, allow for a maximum of 5 open connections to the same HTTP server.
在您的代码中,您不会使用 Google 发送的实际响应.因此,代理假定您尚未完成请求,并将保持连接打开.因此,在 5 个请求之后,代理将不再允许您创建新连接,而是开始等待任何现有连接完成.
In your code, you don't consume the actual response sent by Google. So the agent assumes that you're not done with the request, and will keep the connection open. And so after 5 requests, the agent won't allow you to create a new connection anymore and will start waiting for any of the existing connections to complete.
显而易见的解决方案是只使用数据:
The obvious solution would be to just consume the data:
http.get("http://www.google.com", function(r){
r.on('data', function() { /* do nothing */ });
...
});
如果遇到/api/internetcheck
路由被调用很多的问题,需要允许5个以上的并发连接,可以调大连接池大小,或者只需完全禁用代理(尽管您仍然需要在两种情况下使用数据);
If you run into the problem that your /api/internetcheck
route is called a lot, so you need to allow for more than 5 concurrent connections, you can either up the connection pool size, or just disable the agent completely (although you would still need to consume the data in both cases);
// increase pool size
http.globalAgent.maxSockets = 100;
// disable agent
http.get({ hostname : 'www.google.com', path : '/', agent : false }, ...)
或者使用 HEAD
请求代替 GET
.
Or perhaps use a HEAD
request instead of GET
.
(PS:如果 http.get
产生错误,您仍然应该使用 res.end()
或类似的东西来结束 HTTP 响应).
(PS: in case http.get
generates an error, you should still end the HTTP response by using res.end()
or something like that).
注意:在 Node.js 版本 >= 0.11 中,maxSockets
设置为 Infinity
.
NOTE: in Node.js versions >= 0.11, maxSockets
is set to Infinity
.
这篇关于node.js http.get 在向远程站点发出 5 次请求后挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!