代码之家  ›  专栏  ›  技术社区  ›  Ahmet Can Güven

nodejs http.agent是用于每个实例还是用于每个主机?

  •  0
  • Ahmet Can Güven  · 技术社区  · 6 年前

    我想用不同的设置为每台主机创建连接池。

    const keepAliveAgent = new http.Agent({ 
      keepAlive: true,
      maxSockets: 2,
      keepAliveMsecs: 1000 * 60 * 60
    });
    

    当我在两个不同的主机上使用此代理时。假设我们有如下代码。

    request({
      url: 'https://host1',
      agent: keepAliveAgent
    })
    
    request({
      url: 'https://host2',
      agent: keepAliveAgent
    })
    

    每个主机有2个插槽(总共有4个插槽在使用中)还是只有2个插槽用于这些主机(总共有2个插槽在使用中)?

    documentation

    最大插座 每个主机允许的最大套接字数。每个请求都将使用一个新套接字,直到达到最大值。 默认值:无穷大。

    当我读到这篇文章时,我可以理解2+2个套接字将专用于每个主机,从而导致总共4个套接字打开。

    但是 implementation 没有任何与此相关的代码。有人能澄清一下吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   eol    6 年前

    如您所料,最多使用四个套接字,即在您的情况下,每个主机最多使用两个。负责处理此问题的代码可以在以下位置找到: https://github.com/nodejs/node/blob/master/lib/_http_agent.js#L155

    套接字(除其他外)由主机url标识,将被重用或创建:

      var name = this.getName(options);
      if (!this.sockets[name]) {
        this.sockets[name] = [];
      }
    
      var freeLen = this.freeSockets[name] ? this.freeSockets[name].length : 0;
      var sockLen = freeLen + this.sockets[name].length;
    
      if (freeLen) {
        // we have a free socket, so use that.
        var socket = this.freeSockets[name].shift();
        // Guard against an uninitialized or user supplied Socket.
        if (socket._handle && typeof socket._handle.asyncReset === 'function') {
          // Assign the handle a new asyncId and run any init() hooks.
          socket._handle.asyncReset();
          socket[async_id_symbol] = socket._handle.getAsyncId();
        }
    
        // don't leak
        if (!this.freeSockets[name].length)
          delete this.freeSockets[name];
    
        this.reuseSocket(socket, req);
        setRequestSocket(this, req, socket);
        this.sockets[name].push(socket);
      } else if (sockLen < this.maxSockets) {
        debug('call onSocket', sockLen, freeLen);
        // If we are under maxSockets create a new one.
        this.createSocket(req, options, handleSocketCreation(this, req, true));
      } else {
        debug('wait for socket');
        // We are over limit so we'll add it to the queue.
        if (!this.requests[name]) {
          this.requests[name] = [];
        }
        this.requests[name].push(req);
      }
    

    假设你已经向 host1 而且套接字还没有被释放,一旦有一个套接字可用,请求就会被排队并重新分配到其中一个套接字。此代码负责: https://github.com/nodejs/node/blob/master/lib/_http_agent.js#L66

    推荐文章