13

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 的下一次调用就永远不会(显然)连接。我已经确认我没有收到请求错误。

就好像在响应进来后套接字没有被关闭。

作为响应处理程序的一部分,我需要做些什么来确保套接字已关闭?

这些套接字是否由于默认的保活行为而没有关闭?

我应该如何进行调试?

4

3 回答 3

7

尝试agent: false在选项中设置。默认行为确实是为 HTTP keep-alive 保持连接打开:

var options = {host: 'graph.facebook.com',
               port: 80,
               path: '/' + fb_id + '/picture',
               agent: false};
于 2013-04-09T18:50:11.687 回答
2

Node 的 http 模块声明代理默认为全局代理:http://nodejs.org/api/http.html#http_http_globalagent,这意味着无论发起请求的模块如何,都会共享保持活动状态。

顺便说一句,在 2013 年 4 月 9 日 20:47 回复 Wes 的评论:加载节点模块多少次并不重要,它只会加载一次并由所有模块共享。

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

于 2014-03-24T15:49:02.017 回答
2

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

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

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

对我来说,使用 agent:false 不起作用,因为我发送的大量请求耗尽了服务器资源。

于 2014-07-01T11:54:39.773 回答