我想为每个主机创建具有不同设置的连接池。
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个套接字打开。
但是implementation没有与此相关的任何代码。有人可以澄清吗?
答案 0 :(得分:1)
如您所料,最多将使用四个套接字,即您的情况下每个主机最多两个。可以在以下位置找到负责处理此问题的代码: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