mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
http: add server.keepAliveTimeoutBuffer option
PR-URL: https://github.com/nodejs/node/pull/59243 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jason Zhang <xzha4350@gmail.com>
This commit is contained in:
parent
5bea645e4b
commit
f7c2a7ed4a
3 changed files with 83 additions and 8 deletions
|
@ -1942,18 +1942,39 @@ added: v8.0.0
|
|||
|
||||
The number of milliseconds of inactivity a server needs to wait for additional
|
||||
incoming data, after it has finished writing the last response, before a socket
|
||||
will be destroyed. If the server receives new data before the keep-alive
|
||||
timeout has fired, it will reset the regular inactivity timeout, i.e.,
|
||||
[`server.timeout`][].
|
||||
will be destroyed.
|
||||
|
||||
This timeout value is combined with the
|
||||
\[`server.keepAliveTimeoutBuffer`]\[] option to determine the actual socket
|
||||
timeout, calculated as:
|
||||
socketTimeout = keepAliveTimeout + keepAliveTimeoutBuffer
|
||||
If the server receives new data before the keep-alive timeout has fired, it
|
||||
will reset the regular inactivity timeout, i.e., [`server.timeout`][].
|
||||
|
||||
A value of `0` will disable the keep-alive timeout behavior on incoming
|
||||
connections.
|
||||
A value of `0` makes the http server behave similarly to Node.js versions prior
|
||||
A value of `0` makes the HTTP server behave similarly to Node.js versions prior
|
||||
to 8.0.0, which did not have a keep-alive timeout.
|
||||
|
||||
The socket timeout logic is set up on connection, so changing this value only
|
||||
affects new connections to the server, not any existing connections.
|
||||
|
||||
### `server.keepAliveTimeoutBuffer`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* Type: {number} Timeout in milliseconds. **Default:** `1000` (1 second).
|
||||
|
||||
An additional buffer time added to the
|
||||
[`server.keepAliveTimeout`][] to extend the internal socket timeout.
|
||||
|
||||
This buffer helps reduce connection reset (`ECONNRESET`) errors by increasing
|
||||
the socket timeout slightly beyond the advertised keep-alive timeout.
|
||||
|
||||
This option applies only to new incoming connections.
|
||||
|
||||
### `server[Symbol.asyncDispose]()`
|
||||
|
||||
<!-- YAML
|
||||
|
|
|
@ -25,6 +25,7 @@ const {
|
|||
ArrayIsArray,
|
||||
Error,
|
||||
MathMin,
|
||||
NumberIsFinite,
|
||||
ObjectKeys,
|
||||
ObjectSetPrototypeOf,
|
||||
ReflectApply,
|
||||
|
@ -185,8 +186,6 @@ const kConnections = Symbol('http.server.connections');
|
|||
const kConnectionsCheckingInterval = Symbol('http.server.connectionsCheckingInterval');
|
||||
|
||||
const HTTP_SERVER_TRACE_EVENT_NAME = 'http.server.request';
|
||||
// TODO(jazelly): make this configurable
|
||||
const HTTP_SERVER_KEEP_ALIVE_TIMEOUT_BUFFER = 1000;
|
||||
|
||||
class HTTPServerAsyncResource {
|
||||
constructor(type, socket) {
|
||||
|
@ -486,6 +485,14 @@ function storeHTTPOptions(options) {
|
|||
this.keepAliveTimeout = 5_000; // 5 seconds;
|
||||
}
|
||||
|
||||
const keepAliveTimeoutBuffer = options.keepAliveTimeoutBuffer;
|
||||
if (keepAliveTimeoutBuffer !== undefined) {
|
||||
validateInteger(keepAliveTimeoutBuffer, 'keepAliveTimeoutBuffer', 0);
|
||||
this.keepAliveTimeoutBuffer = keepAliveTimeoutBuffer;
|
||||
} else {
|
||||
this.keepAliveTimeoutBuffer = 1000;
|
||||
}
|
||||
|
||||
const connectionsCheckingInterval = options.connectionsCheckingInterval;
|
||||
if (connectionsCheckingInterval !== undefined) {
|
||||
validateInteger(connectionsCheckingInterval, 'connectionsCheckingInterval', 0);
|
||||
|
@ -548,6 +555,13 @@ function Server(options, requestListener) {
|
|||
}
|
||||
|
||||
storeHTTPOptions.call(this, options);
|
||||
|
||||
// Optional buffer added to the keep-alive timeout when setting socket timeouts.
|
||||
// Helps reduce ECONNRESET errors from clients by extending the internal timeout.
|
||||
// Default is 1000ms if not specified.
|
||||
const buf = options.keepAliveTimeoutBuffer;
|
||||
this.keepAliveTimeoutBuffer =
|
||||
(typeof buf === 'number' && NumberIsFinite(buf) && buf >= 0) ? buf : 1000;
|
||||
net.Server.call(
|
||||
this,
|
||||
{ allowHalfOpen: true, noDelay: options.noDelay ?? true,
|
||||
|
@ -1014,9 +1028,10 @@ function resOnFinish(req, res, socket, state, server) {
|
|||
}
|
||||
} else if (state.outgoing.length === 0) {
|
||||
if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
|
||||
// Increase the internal timeout wrt the advertised value to reduce
|
||||
// Extend the internal timeout by the configured buffer to reduce
|
||||
// the likelihood of ECONNRESET errors.
|
||||
socket.setTimeout(server.keepAliveTimeout + HTTP_SERVER_KEEP_ALIVE_TIMEOUT_BUFFER);
|
||||
// This allows fine-tuning beyond the advertised keepAliveTimeout.
|
||||
socket.setTimeout(server.keepAliveTimeout + server.keepAliveTimeoutBuffer);
|
||||
state.keepAliveTimeoutSet = true;
|
||||
}
|
||||
} else {
|
||||
|
|
39
test/parallel/test-http-keep-alive-timeout-buffer.js
Normal file
39
test/parallel/test-http-keep-alive-timeout-buffer.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
const assert = require('assert');
|
||||
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
const body = 'buffer test\n';
|
||||
|
||||
res.writeHead(200, { 'Content-Length': body.length });
|
||||
res.write(body);
|
||||
res.end();
|
||||
}));
|
||||
|
||||
server.keepAliveTimeout = 100;
|
||||
|
||||
if (server.keepAliveTimeoutBuffer === undefined) {
|
||||
server.keepAliveTimeoutBuffer = 1000;
|
||||
}
|
||||
assert.strictEqual(server.keepAliveTimeoutBuffer, 1000);
|
||||
|
||||
server.listen(0, () => {
|
||||
http.get({
|
||||
port: server.address().port,
|
||||
path: '/',
|
||||
}, (res) => {
|
||||
res.resume();
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
|
||||
{
|
||||
const customBuffer = 3000;
|
||||
const server = http.createServer(() => {});
|
||||
server.keepAliveTimeout = 200;
|
||||
server.keepAliveTimeoutBuffer = customBuffer;
|
||||
assert.strictEqual(server.keepAliveTimeoutBuffer, customBuffer);
|
||||
server.close();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue