diff --git a/.env.example b/.env.example index cc2425f..4937c1b 100644 --- a/.env.example +++ b/.env.example @@ -19,12 +19,12 @@ API_PORT=3334 # Keep API_BIND_HOST as 127.0.0.1 when a reverse proxy terminates public traffic. API_BIND_HOST=127.0.0.1 API_PUBLIC_PORT=3334 -API_MAX_CONNECTIONS=10000 +API_MAX_CONNECTIONS=512 API_REQUEST_TIMEOUT_MS=15000 API_HEADERS_TIMEOUT_MS=10000 API_KEEP_ALIVE_TIMEOUT_MS=5000 -API_SOCKET_TIMEOUT_MS=0 -API_TLS_HANDSHAKE_TIMEOUT_MS=10000 +API_SOCKET_TIMEOUT_MS=15000 +API_TLS_HANDSHAKE_TIMEOUT_MS=3000 API_LISTEN_BACKLOG=1024 API_NODE_ARGS=--max-old-space-size=512 API_MAX_MEMORY_RESTART=768M diff --git a/docker-compose.external-db.yml b/docker-compose.external-db.yml index 400859e..4a842fc 100644 --- a/docker-compose.external-db.yml +++ b/docker-compose.external-db.yml @@ -50,12 +50,12 @@ services: REDIS_URL: ${REDIS_URL:-redis://redis:6379} API_PORT: ${API_PORT:-3334} API_SECURE: ${API_SECURE:-false} - API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-10000} + API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-512} API_REQUEST_TIMEOUT_MS: ${API_REQUEST_TIMEOUT_MS:-15000} API_HEADERS_TIMEOUT_MS: ${API_HEADERS_TIMEOUT_MS:-10000} API_KEEP_ALIVE_TIMEOUT_MS: ${API_KEEP_ALIVE_TIMEOUT_MS:-5000} - API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-0} - API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-10000} + API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-15000} + API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-3000} API_LISTEN_BACKLOG: ${API_LISTEN_BACKLOG:-1024} API_NODE_ARGS: ${API_NODE_ARGS:---max-old-space-size=512} API_MAX_MEMORY_RESTART: ${API_MAX_MEMORY_RESTART:-768M} diff --git a/docker-compose.yml b/docker-compose.yml index b8f3c0d..c02a03e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -79,12 +79,12 @@ services: REDIS_URL: redis://redis:6379 API_PORT: ${API_PORT:-3334} API_SECURE: ${API_SECURE:-false} - API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-10000} + API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-512} API_REQUEST_TIMEOUT_MS: ${API_REQUEST_TIMEOUT_MS:-15000} API_HEADERS_TIMEOUT_MS: ${API_HEADERS_TIMEOUT_MS:-10000} API_KEEP_ALIVE_TIMEOUT_MS: ${API_KEEP_ALIVE_TIMEOUT_MS:-5000} - API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-0} - API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-10000} + API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-15000} + API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-3000} API_LISTEN_BACKLOG: ${API_LISTEN_BACKLOG:-1024} API_NODE_ARGS: ${API_NODE_ARGS:---max-old-space-size=512} API_MAX_MEMORY_RESTART: ${API_MAX_MEMORY_RESTART:-768M} diff --git a/full-setup/docker-compose-mainnet.yml b/full-setup/docker-compose-mainnet.yml index 4b3ba48..baaac49 100644 --- a/full-setup/docker-compose-mainnet.yml +++ b/full-setup/docker-compose-mainnet.yml @@ -99,12 +99,12 @@ services: REDIS_URL: redis://redis:6379 API_PORT: ${API_PORT:-3334} API_SECURE: ${API_SECURE:-false} - API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-10000} + API_MAX_CONNECTIONS: ${API_MAX_CONNECTIONS:-512} API_REQUEST_TIMEOUT_MS: ${API_REQUEST_TIMEOUT_MS:-15000} API_HEADERS_TIMEOUT_MS: ${API_HEADERS_TIMEOUT_MS:-10000} API_KEEP_ALIVE_TIMEOUT_MS: ${API_KEEP_ALIVE_TIMEOUT_MS:-5000} - API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-0} - API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-10000} + API_SOCKET_TIMEOUT_MS: ${API_SOCKET_TIMEOUT_MS:-15000} + API_TLS_HANDSHAKE_TIMEOUT_MS: ${API_TLS_HANDSHAKE_TIMEOUT_MS:-3000} API_LISTEN_BACKLOG: ${API_LISTEN_BACKLOG:-1024} API_NODE_ARGS: ${API_NODE_ARGS:---max-old-space-size=512} API_MAX_MEMORY_RESTART: ${API_MAX_MEMORY_RESTART:-768M} diff --git a/src/main.ts b/src/main.ts index 3dbef5c..ab9c58a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,12 +9,12 @@ import * as ecc from 'tiny-secp256k1'; import { AppModule } from './app.module'; -const DEFAULT_API_MAX_CONNECTIONS = 10000; +const DEFAULT_API_MAX_CONNECTIONS = 512; const DEFAULT_API_REQUEST_TIMEOUT_MS = 15000; const DEFAULT_API_HEADERS_TIMEOUT_MS = 10000; const DEFAULT_API_KEEP_ALIVE_TIMEOUT_MS = 5000; -const DEFAULT_API_SOCKET_TIMEOUT_MS = 0; -const DEFAULT_API_TLS_HANDSHAKE_TIMEOUT_MS = 10000; +const DEFAULT_API_SOCKET_TIMEOUT_MS = 15000; +const DEFAULT_API_TLS_HANDSHAKE_TIMEOUT_MS = 3000; const DEFAULT_API_LISTEN_BACKLOG = 1024; async function bootstrap() { @@ -128,11 +128,20 @@ async function bootstrap() { } function configureApiServer(server: any) { + const socketTimeoutMs = getPositiveIntegerEnv('API_SOCKET_TIMEOUT_MS', DEFAULT_API_SOCKET_TIMEOUT_MS); + server.maxConnections = getPositiveIntegerEnv('API_MAX_CONNECTIONS', DEFAULT_API_MAX_CONNECTIONS); server.requestTimeout = getPositiveIntegerEnv('API_REQUEST_TIMEOUT_MS', DEFAULT_API_REQUEST_TIMEOUT_MS); server.headersTimeout = getPositiveIntegerEnv('API_HEADERS_TIMEOUT_MS', DEFAULT_API_HEADERS_TIMEOUT_MS); server.keepAliveTimeout = getPositiveIntegerEnv('API_KEEP_ALIVE_TIMEOUT_MS', DEFAULT_API_KEEP_ALIVE_TIMEOUT_MS); - server.timeout = getNonNegativeIntegerEnv('API_SOCKET_TIMEOUT_MS', DEFAULT_API_SOCKET_TIMEOUT_MS); + server.timeout = socketTimeoutMs; + + server.on('connection', (socket: NodeJS.ReadWriteStream & { setTimeout?: (ms: number) => void; destroy?: () => void }) => { + socket.setTimeout?.(socketTimeoutMs); + socket.once?.('timeout', () => { + socket.destroy?.(); + }); + }); } function getPositiveIntegerEnv(name: string, fallback: number) { @@ -140,9 +149,4 @@ function getPositiveIntegerEnv(name: string, fallback: number) { return Number.isInteger(value) && value > 0 ? value : fallback; } -function getNonNegativeIntegerEnv(name: string, fallback: number) { - const value = Number(process.env[name]); - return Number.isInteger(value) && value >= 0 ? value : fallback; -} - bootstrap();