首页 > 解决方案 > NodeJs http.Agent 是用于每个实例还是每个主机?

问题描述

我想为每个主机创建具有不同设置的连接池。

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 个正在使用的套接字)?

文档中

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

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

但是实现没有任何与此相关的代码。有人可以澄清一下吗?

标签: node.jssockets

解决方案


如您所料,最多将使用四个套接字,即在您的情况下,每个主机最多两个。可以在此处找到负责处理此问题的代码: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


推荐阅读