Ste*_*ast 6 keep-alive node.js axios
我正在使用axios发出HTTP请求。
当在Node中使用时,axios提供了new http.Agent()
在请求配置中指定的选项。
该HTTP代理选项有:
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.
}
Run Code Online (Sandbox Code Playgroud)
还有带有和选项的HTTP标头。timeout
max
选项似乎并没有对齐(keepAliveMsecs
,maxSockets
和maxFreeSockets
vs timeout
和max
),这表明它们是不同的。
Node new Agent({ keepAlive: true })
和HTTP标头Keep-Alive: timeout=5, max=1000
..有什么区别?
jpe*_*erl 28
这是基于我自己收集的。
HTTP 标头Keep-Alive: timeout=5, max=1000
只是随 HTTP 请求一起发送的标头。将其视为在两台主机(客户端和服务器)之间进行通信的一种方式。主持人说'嘿,请保持连接有效'。这对于现代浏览器来说是自动的,服务器可能会实现也可能不会实现。该keepAlive: true
代理是作为文档说:
不要与 Connection 标头的 keep-alive 值混淆。
这意味着keepAlive: false
!= Connection: close
。它与标题没有任何关系。代理将处理 TCP 级别的事务,包括 HTTP 客户端上的套接字等。
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
Run Code Online (Sandbox Code Playgroud)
代理究竟是什么?
代理负责管理 HTTP 客户端的连接持久性和重用。它维护一个给定主机和端口的待处理请求队列,为每个重用单个套接字连接,直到队列为空,此时套接字要么被销毁,要么放入一个池中,以便再次用于请求到相同的主机和端口。是销毁还是池化取决于keepAlive选项。
池连接为它们启用了 TCP Keep-Alive,但服务器可能仍会关闭空闲连接,在这种情况下,它们将从池中删除,并在为该主机和端口发出新的 HTTP 请求时建立新连接。服务器也可能拒绝允许通过同一个连接的多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能合并。代理仍将向该服务器发出请求,但每个请求都将通过新连接发生。
关于timeout和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
Run Code Online (Sandbox Code Playgroud)
这使
Connection:Keep-Alive
Keep-Alive:timeout=5, max=100
Run Code Online (Sandbox Code Playgroud)
但是这些与 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
Run Code Online (Sandbox Code Playgroud)
服务器是一个快速应用程序(我将跳过详细信息)
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);
});
});
Run Code Online (Sandbox Code Playgroud)
为了让您看到keepAlive: false
!= Connection: close
,让 keepAlive 设置为 false 并查看服务器端会发生什么。
agent: new http.Agent({
keepAlive: false,
maxSockets: 20
})
Run Code Online (Sandbox Code Playgroud)
服务器
客户
如您所见,我没有将 maxSockets 设置为 Infinity,因此即使代理中的 keepAlive 设置为 false,Connection 标头也设置为 Keep-Alive。但是,每次向服务器发送请求时,服务器上的套接字都会在每次请求后立即关闭。让我们看看当我们将 keepAlive 设置为 true 时会发生什么。
服务器
客户
这一次,只使用了一个插座。客户端和服务器之间存在持久连接,该连接持续超过单个请求。
由于这篇很棒的文章,我了解到的一件事是,在 Firefox 上,您一次可以拥有多达 6 个并发持久连接。您可以通过将 maxSockets 设置为 6 来使用代理重现这一点。出于测试目的,我将其设置为 2。而且,我不会从服务器返回任何内容,因此连接将保持挂起。
agent: new http.Agent({
keepAlive: true,
maxSockets: 2,
}),
Run Code Online (Sandbox Code Playgroud)
//res.send('response from the server');
Run Code Online (Sandbox Code Playgroud)
服务器
客户
客户端不断发送请求,但服务器只收到了两个请求。然而两分钟后,看到http_server_timeout
假定套接字超时之前不活动的毫秒数。
接受两个新请求。实际上,客户端已将后续请求排入队列,一旦服务器释放套接字,客户端就能够从队列中发送两个新请求。
所以,我希望这会有所帮助。
归档时间: |
|
查看次数: |
782 次 |
最近记录: |