使用Node.js http.get时,套接字似乎没有关闭

时间:2013-04-09 18:36:46

标签: node.js sockets http

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行为,这些套接字是否未关闭?

我应该如何进行调试?

3 个答案:

答案 0 :(得分:7)

尝试在选项中设置agent: false。默认行为确实是为了保持HTTP保持连接的连接:

var options = {host: 'graph.facebook.com',
               port: 80,
               path: '/' + fb_id + '/picture',
               agent: false};

答案 1 :(得分:2)

Node的http模块声明代理默认为全局代理:http://nodejs.org/api/http.html#http_http_globalagent,这意味着无论源于请求的模块是什么,都会共享keep-alive。

顺便说一句,回应Wes' 4月9日和13日20:47的评论:加载节点模块的次数无关紧要,它只会加载一次并由所有模块共享。

您遇到的问题是游泳池耗尽问题。避免它的最简单方法是使用具有所需maxSockets的新代理(http://nodejs.org/api/http.html#http_class_http_agent)。请记住,如果将模块放在该模块的导出中,则可以在模块之间共享您创建的代理(节点中的模块是有状态的!)。

答案 2 :(得分:2)

我经历了相同的行为,除了我的连接最终在超时期限后重复使用。检查连接是否在一段时间(几分钟)后重复使用,并检查响应头是否包含“连接:保持活动”。

如果是这种情况,可能的解决方案是使用“连接:关闭”#39;标头而不是保持活动,这样的池连接可以像通常的设置一样重新使用。我不确定这是否会导致使用facebook端点出现任何性能问题。

var options = {host: 'graph.facebook.com',
               port: 80,
               path: '/' + fb_id + '/picture',
               headers: { 'Connection':'Close' }
};

对于我使用代理:false无法正常工作,因为我发送的大量请求耗尽了服务器资源。