Траблшутинг upstream keepalive в Nginx: постоянные соединения с бэкендом
- Сервер быстро исчерпывает локальные эфемерные порты (ошибки
Cannot assign requested address). - Тысячи соединений зависают в состоянии
TIME_WAITв выводеnetstat/ss. - Высокая сетевая задержка (Latency) из-за постоянного выполнения 3-way TCP Handshake и TLS ренегоциации для каждого запроса к бэкенду.
1. Настройка блока upstream с пулом keepalive сокетов
Отредактируйте конфигурационный файл Nginx:
upstream app_backend {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
# Максимальное количество неактивных keepalive-соединений в пуле каждого воркера
keepalive 64;
# Общее количество запросов, обслуживаемых через одно постоянное соединение
keepalive_requests 1000;
# Время удержания неактивного постоянного соединения
keepalive_timeout 60s;
}2. Корректная настройка блока location (Критически важно!)
По умолчанию Nginx проксирует запросы по протоколу HTTP/1.0 и закрывает соединение. Для работы keepalive необходимо принудительно включить HTTP/1.1 и очистить заголовок Connection:
server {
listen 443 ssl http2;
server_name api.itstm.ru;
location / {
proxy_pass http://app_backend;
# 1. Принудительный HTTP/1.1
proxy_http_version 1.1;
# 2. Очистка заголовка 'Connection: close'
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}3. Проверка сокращения сокетов TIME_WAIT
nginx -t && systemctl reload nginx
ss -tan state time-wait | wc -l Частые вопросы (FAQ)
Почему keepalive не работает при наличии директивы keepalive в upstream?
В 99% случаев забывают добавить proxy_set_header Connection "" и proxy_http_version 1.1. Nginx отправляет заголовок 'Connection: close', и бэкенд разрывает TCP сессию сразу после ответа.
Ограничивает ли параметр keepalive 64 максимальное число подключений?
Нет, параметр keepalive задает только число свободных (idle) соединений, сохраняемых в кэше воркера. Общее число активных соединений не ограничивается.