34

有人可以解释如何使用 request.js 池哈希吗?

github的注释是关于池的:

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

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

我有这个用于写入 CouchDB 实例的代码(注意问号)。基本上,任何连接到我的节点服务器的用户都将相互独立地写入数据库:

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”数的缺点是什么?
如何创建一个单独的池来使用而不是全局池?为什么我只想创建一个单独的池?

4

2 回答 2

48

http.Agent请求中的池选项使用与标准 http 库相同的代理。请参阅http.Agent的文档并查看http.requestagent中的选项。

用法

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. 此选项仅在传递选项时才有意义pool

如此不同的使用方式:

  1. 不给agent选项,会undefinedhttp.globalAgent。默认情况。
  2. 将其设为 false,将禁用池化。
  3. 提供您自己的代理,如上面的示例。

反过来回答你的问题。

池旨在保留一定数量的套接字供程序使用。首先,套接字被重用于不同的请求。因此它减少了创建新套接字的开销。其次,它使用较少的套接字进行请求,但始终如一。它不会占用所有可用的套接字。第三,它维护请求队列。所以隐含了等待时间。

池既像缓存又像节流阀。如果您有更多的请求和更少的套接字,节流效果将更加明显。使用全局池时,它可能会限制两个不同客户端的功能,不能保证等待时间。为他们提供单独的池对两者都更公平(想想如果一个请求比另一个请求更多)。

maxSockets 属性提供了可能的最大并发性。它增加了整体吞吐量/性能。缺点是油门效果降低。您无法控制峰值开销。将其设置为大数字,就像根本没有池化一样。您将开始收到诸如套接字不可用之类的错误。它不能超过操作系统设置的允许的最大限制。

那么什么最适合高吞吐量/性能?吞吐量有物理限制。如果达到限制,响应时间将随着连接数的增加而增加。在那之前你可以继续增加 maxSockets,但在那之后增加它就无济于事了。

于 2013-09-30T18:29:47.633 回答
14

你应该看看forever-agent模块,它是http.Agent的包装器。

通常池是一个包含多个http代理的哈希对象。它试图重用“keep-alive”连接中创建的套接字。每个主机:端口。例如,您对主机 www.domain1.com:80 和 www.domain2.com:80 执行了多个请求,如果任何响应不包含 header Connection: close,它将把套接字放入池中并将其提供给未决请求。

如果没有挂起的请求需要这个池化套接字,它将被销毁。

表示单个主机的maxSockets最大并发套接字:端口,默认值为5。我建议将这个值与您的场景一起考虑:

  • 根据那些热点站点的请求访问,你最好创建单独的池。以便新请求可以非常快速地获取空闲套接字。maxSockets关键是,您需要通过增加池的价值来减少对某些站点的待处理请求的数量。maxSockets请注意,当源服务器通过响应标头很好地管理连接时,您是否设置一个非常高的数字并不重要Connection: close

  • 根据您的请求几乎不访问的站点,使用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){
});
于 2013-09-30T01:53:43.727 回答