Keepalive до апстрима в nginx: где теряются соединения
По умолчанию nginx общается с апстримом по HTTP/1.0 и закрывает соединение после каждого ответа. При высокой нагрузке это тысячи сокетов в TIME_WAIT и лишние миллисекунды на установку TCP, а для HTTPS-апстрима ещё и полный TLS-хендшейк.
Минимальная настройка
upstream app {
server 10.0.0.5:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Важны все три строки. Без proxy_http_version 1.1 keepalive не работает, а без очистки заголовка Connection клиентский close уедет к апстриму.
Как проверить
ss -tan state time-wait '( dport = :8080 )' | wc -l
До изменения счётчик растёт вместе с RPS, после — держится около нуля, а число установленных соединений примерно равно значению keepalive, умноженному на число воркеров.
Подводные камни
keepalive— это размер пула простаивающих соединений на воркер, а не лимит.- Апстрим может закрывать соединения раньше nginx. Держите
keepalive_timeoutв upstream меньше, чем таймаут приложения. - Для WebSocket нужен отдельный location с заголовками
Upgrade.