Nginx upstream keepalive: переиспользовать соединения

Категория: Nginx · Обновлено:

По умолчанию Nginx открывает новое соединение к upstream на каждый запрос. Директива keepalive в блоке upstream хранит idle-соединения и переиспользует их, снижая задержку и число TCP-handshake. Чтобы это работало, нужен HTTP/1.1 и правильная очистка заголовка Connection.

Включить пул соединений к бэкенду

Текст
upstream api_backend {
    server 127.0.0.1:8000;
    keepalive 32;
    keepalive_requests 1000;
    keepalive_timeout 60s;
}

server {
    listen 80;

    location /api/ {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://api_backend;
    }
}

keepalive 32 задаёт максимальное число простаивающих соединений на worker, а не общий лимит. keepalive_requests ограничивает число запросов через одно соединение, keepalive_timeout — время жизни idle-соединения. Значения должны соответствовать возможностям бэкенда и лимиту worker_connections.

Без proxy_http_version 1.1 Nginx общается с upstream по HTTP/1.0, где keepalive не работает так, как ожидается. Заголовок Connection: close от клиента или из конфигурации закрывает соединение; proxy_set_header Connection ""; очищает его перед отправкой. Некоторые приложения сами присылают Connection: close, и тогда пул не поможет.

Не ставьте keepalive слишком большим: idle-соединения занимают файловые дескрипторы и память. Для сотен upstream-серверов и высоких worker_connections считайте бюджет. Проверяйте, что балансировщик и firewall не разрывают соединение раньше keepalive_timeout.

Для gRPC и HTTP/2 нужны отдельные настройки (grpc_pass, http2), а не этот рецепт. Если upstream — PostgreSQL или Redis, используется stream-модуль с другими директивами. После изменений выполните nginx -t и перезагрузите Nginx.

Документация: upstream keepalive, proxy_http_version.