【问题标题】:How to use Request js (Node js Module) pools如何使用 Request js(Node js 模块)池
【发布时间】:2013-10-01 03:52:22
【问题描述】:

谁能解释一下如何使用 request.js 池哈希?

github notes 这么说池:

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

【问题讨论】:

    标签: node.js


    【解决方案1】:

    请求中的池选项使用与标准 http 库中的http.Agent 相同的代理。请参阅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. 提供您自己的代理,如上例。

    反过来回答你的问题。

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

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

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

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

    【讨论】:

    • 在您的第一个用法示例中,第二行 http.request( {...} ); 的意义是什么——这只是为了表明它在使用核心 HTTP 模块时会起作用,还是需要调用的语句为了正确初始化池以在request 库中使用?谢谢!
    • 您的答案是迄今为止我获得的关于代理池以及使用它们的优缺点的最佳资源。非常感谢您花时间写这篇文章(y)
    • 注意最新版本的 Node.js 默认将Infinity 作为maxSockets
    • 请求中的池选项应该是一个对象,而不是一个代理的实例。这个示例用法对我有用。起作用的是通过{ agentClass: http.Agent, pool: { maxSockets: N } }
    【解决方案2】:

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

    一般来说pool是一个包含多个http代理的hash对象。它试图重用从“keep-alive”连接创建的套接字。每个主机:端口。例如,您对主机 www.domain1.com:80 和 www.domain2.com:80 执行了多个请求,如果任何响应不包含标头 Connection: close,它会将套接字放入池中并将其提供给待处理的请求。

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

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

    • 根据那些热点站点的请求访问,你最好创建单独的池。以便新请求可以非常快速地获取空闲套接字。关键是,您需要通过增加池的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){
    });
    

    【讨论】:

    • 这个“sepearateReqPool”似乎对我有用,而且代码少了很多。不确定永久代理位(没有尝试),但后半部分非常有帮助。
    • 如果我设置 pool: false ,操作系统会接管吗?我的意思是,它仍然会重用保持连接,还是那是专有的应用程序逻辑?
    • @lucaswxp 操作系统没有 http keep-alives 的概念,不会接管。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2015-08-21
    • 1970-01-01
    相关资源
    最近更新 更多