我使用axios发出HTTP请求。
axios提供了在节点中使用时在request config中指定new http.Agent()
的选项。
http Agent选项包括:
const agentOptions = {
keepAlive: true, // Keep sockets around even when there are no outstanding requests, so they can be used for future requests without having to reestablish a TCP connection. Defaults to false
keepAliveMsecs: 1000, // When using the keepAlive option, specifies the initial delay for TCP Keep-Alive packets. Ignored when the keepAlive option is false or undefined. Defaults to 1000.
maxSockets: Infinity, // Maximum number of sockets to allow per host. Defaults to Infinity.
maxFreeSockets: 256 // Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Defaults to 256.
}
HTTP header还有timeout
和max
选项。
这些选项似乎不排成一行(keepAliveMsecs
,maxSockets
和maxFreeSockets
vs timeout
和max
),这表明它们是不同。
Node new Agent({ keepAlive: true })
与HTTP标头Keep-Alive: timeout=5, max=1000
之间的区别是什么?
答案 0 :(得分:3)
首先,感谢您的提问,我之前从未对保持活力有太多了解。
HTTP标头Keep-Alive: timeout=5, max=1000
只是随HTTP请求发送的标头。将其视为在两个主机(客户端和服务器)之间进行通信的一种方式。主持人说:“嘿,请保持连接活跃”。这对于现代浏览器是自动的,服务器可能会实现也可能不会实现。代理人的keepAlive: true
如documentation所说
不要与Connection标头的keep-alive值混淆。
这意味着keepAlive: false
!= Connection: close
。它实际上与标题没有任何关系。该代理将使用套接字和 HTTP客户端在TCP级别处理事务。
keepAlive boolean即使没有未处理的请求,也保留套接字,因此它们可用于将来的请求而不必重新建立TCP连接
将代理用于HTTP客户端后,将立即使用Connection: Keep-Alive
。 除非,keepAlive
设置为false
,maxSockets
设置为Infinity
。
const options = {
port: 3000,
agent: new http.Agent({
keepAlive: false ,
maxSockets: Infinity,
})
};//----> Connection: close
agent到底是什么?
代理负责管理HTTP客户端的连接持久性和重用。它为给定的主机和端口维护一个待处理请求队列,为每个主机和端口重用单个套接字连接,直到队列为空,此时该套接字要么被销毁,要么被放入池中,以便再次用于请求到相同的主机和端口。它是被销毁还是被池化取决于keepAlive选项。
池连接为它们启用了TCP Keep-Alive,但是服务器仍可以关闭空闲连接,在这种情况下,它们将从池中删除,并且当对该主机和主机发出新的HTTP请求时将建立新的连接。港口。服务器也可能拒绝允许通过同一连接的多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能将其合并。代理仍会向该服务器发出请求,但每个请求都将通过新的连接发生。
据我所知,关于超时和 max ,在为Apache添加配置时会自动设置这些设置
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5
给出
Connection:Keep-Alive
Keep-Alive:timeout=5, max=100
但是这些与NodeJS无关吗?我会让更多有经验的人回答这个问题。无论如何,除非如上所述,否则除非将Connection: Keep-Alive
设置为keepAlive
并将false
设置为maxSockets
,否则代理将不会进行设置,也不会修改Infinity
。>
但是,要使代理配置具有任何含义,必须将Connection
设置为Keep-Alive
。
好的,现在做一个小实验,看看代理在工作!
我已经设置了一个客户端进行测试(由于axios
始终使用http.agent
作为代理,因此我只使用了http
)。
const http = require('http');
const options = {
port: 3000,
agent: new http.Agent({
keepAlive: true,
maxSockets: 2,
}),
// headers: {
// 'Connection': 'close'
// }
};
var i = 0;
function request() {
console.log(`${++i} - making a request`);
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.end();
}
setInterval(function(){ request(); }, 3000); // send a request every 3 seconds
服务器是快速应用程序(我将跳过详细信息)
server.on('connection', function(socket) {
socket.id = shortid.generate();
//socket.setTimeout(500)
console.log("A new connection was made by a client." + ` SOCKET ${ socket.id }`);
socket.on('end', function() {
console.log(`SOCKET ${ socket.id } END: other end of the socket sends a FIN packet`);
});
socket.on('timeout', function() {
console.log(`SOCKET ${ socket.id } TIMEOUT`);
});
socket.on('error', function(error) {
console.log(`SOCKET ${ socket.id } ERROR: ` + JSON.stringify(error));
});
socket.on('close', function(had_error) {
console.log(`SOCKET ${ socket.id } CLOSED. IT WAS ERROR: ` + had_error);
});
});
要让您看到keepAlive: false
!= Connection: close
,请将keepAlive设置为false并查看服务器端会发生什么情况。
agent: new http.Agent({
keepAlive: false,
maxSockets: 20
})
服务器
客户
如您所见,我没有将maxSockets设置为Infinity,因此即使代理中的keepAlive设置为false,Connection头也设置为Keep-Alive。但是,每次将请求发送到服务器时,每个请求后都会立即关闭服务器上的套接字。让我们看看将keepAlive设置为true会发生什么。
服务器
客户
这一次,仅使用了一个插槽。客户端和服务器之间存在持久连接,并且该连接超出了单个请求。
由于great article,我了解到的一件事是,在Firefox上,一次最多可以有6个并发持久连接。而且,您可以通过将maxSockets设置为6来使用代理来重现此内容。出于测试目的,我将其设置为2。此外,我不会从服务器返回任何内容,因此连接将被挂起。
agent: new http.Agent({
keepAlive: true,
maxSockets: 2,
}),
//res.send('response from the server');
服务器
客户
客户端继续发送请求,但服务器仅接收到两个请求。两分钟后,请参见http_server_timeout
假定套接字超时之前闲置的毫秒数。
两个新请求被接受。实际上,客户端已经将后续请求排队,一旦服务器释放了套接字,客户端就可以从队列中发送两个新请求。
所以,我希望这会有所帮助。