OS X 10.8.3
节点0.10.0
我正在使用'http'模块来请求Facebook图形API。
以下是我传递给'http.get'的选项:
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture'}; //fb_id is a Facebook user identifier
我的代码如下所示:
http.get(options,
function(res) {
...some stuff...
DONE(RESULT); //DONE is a callback function
}).on('error', function(e) {
...some error handling...
});
我观察到的是我只能执行与http.globalAgent.maxSockets值相同的请求。一旦我达到了那么多请求,下一次对http.get的调用永远(显然)连接。我已经确认我没有收到错误的请求。
好像响应进来后套接字没有关闭。
作为响应处理程序的一部分,我需要做些什么才能确保套接字关闭?
由于默认的keepalive行为,这些套接字是否未关闭?
我该如何进行调试呢?
尝试设置 agent: false
在选项中。默认行为确实是为了保持HTTP保持连接的连接:
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture',
agent: false};
尝试设置 agent: false
在选项中。默认行为确实是为了保持HTTP保持连接的连接:
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture',
agent: false};
Node的http模块声明代理默认为全局代理: http://nodejs.org/api/http.html#http_http_globalagent,这意味着无论发起请求的模块是什么,都会共享keep-alive。
BTW,回应Wes在2013年4月9日20:47发表的评论:加载节点模块的次数无关紧要,它只会加载一次并由所有模块共享。
您遇到的是游泳池耗尽问题。避免它的最简单方法是使用新代理(http://nodejs.org/api/http.html#http_class_http_agent)使用您想要的maxSockets。请记住,如果将模块放在该模块的导出中,则可以在模块之间共享您创建的代理(节点中的模块是有状态的!!!)。
我经历了相同的行为,除了我的连接最终在超时期后重复使用。检查连接是否在一段时间(几分钟)后重复使用,并检查响应头是否包含“Connection:keep-alive”。
如果是这种情况,可能的解决方案是使用'Connection:Close'标头而不是keep-alive,那么池化连接可以像通常的设置一样重新使用。我不确定这是否会导致使用facebook端点出现任何性能问题。
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture',
headers: { 'Connection':'Close' }
};
对我来说使用agent:false没有用,因为我发送了大量请求耗尽了服务器资源。