2013-09-27 74 views
31

有人能解释如何使用request.js池哈希?如何使用请求JS(节点JS模块)池

github notes说,这大约池:

池 - 包含这些请求代理的哈希对象。如果省略,则该请求将使用设置为节点的默认maxSockets的全局池。

pool.maxSockets - 包含在池中的套接字的最大量整数。

我有写这个代码写入一个CouchDB实例(注意问号)。基本上,谁连接到我的节点服务器的任何用户将写信给对方的DB独立:

var request = require('request'); 

request({ 
    //pool:,  // ?????????????????? 
    'pool.maxSockets' : 100, // ?????????????????? 
    'method' : 'PUT', 
    'timeout' : 4000, 
    'strictSSL' : true, 
    'auth' : { 
     'username' : myUsername, 
     'password' : myPassword 
    }, 
    'headers' : { 
     'Content-Type': 'application/json;charset=utf-8', 
     'Content-Length': myData.length 
    }, 
    'json' : myData, 
    'url': myURL 
}, function (error, response, body){ 
    if (error == null) { 
     log('Success: ' + body); 
    } 
    else { 
     log('Error: ' + error); 
    } 
}); 

什么是最好的高吞吐量/性能?
高'maxSockets'数字有什么缺点?
如何创建一个单独的池来使用而不是全局池?为什么我只想创建一个单独的池?

回答

38

在请求池中选项使用剂是相同http.Agent从标准的HTTP库。请参阅http.Agent的文档,并参阅http.request中的agent选项。

使用

pool = new http.Agent(); //Your pool/agent 
http.request({hostname:'localhost', port:80, path:'/', agent:pool}); 
request({url:"http://www.google.com", pool:pool }); 

如果你想知道那是什么,你可以从控制台中看到它。

{ domain: null, 
    _events: { free: [Function] }, 
    _maxListeners: 10, 
    options: {}, 
    requests: {}, 
    sockets: {}, 
    maxSockets: 5, 
    createConnection: [Function] } 

maxSockets决定有多少并发套接字代理可以为每个主机的开放,是默认值为5.通常,您将之前设置的代理存在。显式传递pool.maxSockets将覆盖pool中的maxSockets属性。此选项只有在传递pool选项时才有意义。

所以不同的方式来使用它:

  1. 不要给agent选项,将undefined将使用http.globalAgent。默认情况。
  2. 将其作为false将会禁用共享池。
  3. 提供您自己的代理,就像上面的例子。

以相反的方式回答您的问题。

池是为了保持一定数量的套接字被程序使用。首先,套接字被重用于不同的请求。所以它减少了创建新套接字的开销。其次,它使用较少的套接字来处理请求,但始终如一。它不会占用所有可用的插座。第三,它维护请求队列。所以有暗示的等待时间。

池充当缓存和节流阀。如果你有更多的请求和更少的套接字,节流效果将更明显。使用全局池时,可能会限制两个不同客户端的功能,等待时间没有保证。为他们分开游泳池将会更公平(想想如果有人要求比其他更多)。

maxSockets属性提供了最大的并发可能性。它增加了整体吞吐量/性能。缺点是节流效果降低。您无法控制峰值开销。将它设置为大数目,将会像没有共享池一样。你会开始得到像socket这样的错误不可用。它不能超过操作系统所允许的最大限制。

那么什么是最好的高吞吐量/性能?吞吐量有物理限制。如果达到极限,响应时间将随着连接数量的增加而增加。到那时你可以继续增加maxSockets,但在增加之后它不会有帮助。

+0

在你的第一个使用示例中,第二行'http.request({...})的含义是什么? - 这仅仅是为了表明它在使用核心HTTP模块时工作,或者是需要声明被调用是为了正确地初始化在'request'库中使用的池?谢谢! – 2016-07-01 04:26:22

+0

您的回答是我迄今为止获得的关于代理池和使用它们的利弊的最佳资源。非常感谢您花时间编写这个(y) –

+0

**注意**最近版本的_Node.js_在默认情况下具有'Infinity'作为'maxSockets'。 –

13

你应该看看forever-agent模块,这是一个包装http.Agent

通常该池是包含多个HTTP代理的散列对象。它试图从“保持活动”连接中重用创建的套接字。每主机:端口。例如,您执行了多个请求来托管www.domain1.com:80和www.domain2.com:80,如果任何响应中不包含标头Connection: close,它会将该套接字放入池中并将其提交给未决请求。

如果没有挂起的请求,需要这个汇集插座,它就会被破坏。

maxSockets表示单个主机端口的最大并发套接字,默认值为。我会建议你一起考虑这个价值与你的情况:

  • 根据那些热点请求访问,你最好创建单独的池。所以新的请求可以非常快速地提取空闲套接字。问题是,您需要通过增加池的值来减少对某些站点的未决请求数。请注意,当连接由原始服务器通过响应标头Connection: close管理良好时,如果将极高数字设置为maxSockets,则无关紧要。

  • 根据这些,你的请求很难访问的网站,使用pool: false禁用池。

您可以用这种方式来指定不同的池您的要求:

// create a separate socket pool with 10 concurrent sockets as max value. 
var separateReqPool = {maxSockets: 10}; 
var request = require('request'); 

request({url: 'http://localhost:8080/', pool: separateReqPool}, function(e, resp){ 
}); 
+2

这个“sepearateReqPool”似乎适用于我,而且代码少得多。不知道永远的代理位(没有尝试),但下半年是非常有帮助的。 – jeremy

+0

如果我设置了池,操作系统是否会被接管:false?我的意思是,它仍然会重用保持连接的连接,还是独占的应用程序逻辑? – lucaswxp