Тюнинг Nginx на 50 тысяч соединений: цифры до и после
50 тысяч соединений упираются не в одну директиву Nginx. Нужны свободные файловые дескрипторы, правильное число workers, проверка ядра и измерения до и после изменений — иначе тюнинг превращается в набор случайных параметров.

При 50 тысячах TCP-соединений Nginx чаще ломается не из-за пропускной способности, а из-за лимита файловых дескрипторов, неверного расчёта worker_connections и слишком долгих keep-alive. Универсальных цифр «до и после» нет: результат зависит от размера ответов, доли долгих соединений, числа upstream-запросов, CPU и ядра Linux. Ниже — схема настройки для NGINX Open Source 1.26.x и способ получить честные замеры, не выдавая расчётные значения за бенчмарк.
Что означает 50 тысяч соединений
В Nginx соединение — это файловый дескриптор. Клиентский сокет занимает один дескриптор, а при проксировании запроса к приложению добавляется ещё один дескриптор upstream. Поэтому 50 тысяч клиентов не всегда означают 50 тысяч открытых файлов.
Директива worker_connections задаёт максимальное число одновременных соединений на один worker, но включает не только клиентов. Для прокси в лимит попадают также соединения к бэкендам, а часть дескрипторов нужна для логов, файлов и служебных операций.
При четырёх workers и значении worker_connections 65535 теоретический потолок составляет 262 140 соединений. Это не означает, что сервер выдержит столько клиентов: первым ограничением может стать RLIMIT_NOFILE, память, backlog ядра, upstream или сетевой канал.
50 тысяч соединений — это не цель для одной директивы, а бюджет ресурсов. Сначала посчитайте дескрипторы и память, затем меняйте Nginx.
Сноска. Файловый дескриптор — числовой идентификатор открытого файла, сокета или другого ресурса процесса в Unix-системе. Лимит процесса и лимит, заданный в конфигурации Nginx, должны позволять workers открыть нужное количество дескрипторов.
Цифры до и после: что сравнивать
До изменения конфигурации сохраните исходные значения и нагрузочный профиль. После — повторите тот же тест: одинаковый URL, размер ответа, количество клиентов, длительность, доля keep-alive и состояние приложения. Если изменить одновременно Nginx, ядро и бэкенд, вы не поймёте, что именно дало эффект.
| Параметр | До: типичная база | После: расчётная настройка | Что измерять |
|---|---|---|---|
| Workers | 1 или фиксированное число | worker_processes auto | Загрузка CPU по ядрам и число worker-процессов |
| Соединения на worker | Значение по умолчанию Nginx — 512 | 65535 как верхний рабочий лимит, если хватает FD | Активные соединения и ошибки открытия сокетов |
| Лимит открытых файлов | Проверяется в /proc или systemd | Например, 131072 на процесс с запасом | open() failed, too many open files |
| Keep-alive | Долгий тайм-аут удерживает сокеты | Подбирается по профилю, часто начинают с 15 секунд | Число idle-соединений и задержка повторного запроса |
В таблице нет гарантии прироста RPS. Значение 65535 — вместимость, а не производительность. Если 50 тысяч клиентов держат соединения без запросов, нагрузка на CPU может почти не измениться, но память и файловые дескрипторы всё равно будут заняты.
Базовая конфигурация для Linux
Для Linux с epoll начните с минимального набора изменений. Конфигурация рассчитана на NGINX Open Source 1.26.x и не включает настройки TLS, gzip или прокси: они меняют профиль нагрузки и должны измеряться отдельно.
worker_processes auto;
worker_rlimit_nofile 131072;
events {
use epoll;
worker_connections 65535;
multi_accept off;
}
http {
sendfile on;
tcp_nopush on;
keepalive_timeout 15s;
keepalive_requests 1000;
reset_timedout_connection on;
}
В примере оставлен multi_accept off. Включение этой директивы заставляет worker принимать сразу несколько новых соединений за событие, но при резком наплыве это может отнять CPU у обработки уже принятых запросов. Меняйте её только после отдельного сравнения.
sendfile полезен для отдачи статических файлов, а tcp_nopush имеет смысл вместе с ним. Для API, который почти не отдаёт файлы с диска, эти параметры не заменят оптимизацию приложения.
Лимит systemd важнее строки в nginx.conf
Если Nginx запущен через systemd, задайте лимит для сервиса. Одной директивы worker_rlimit_nofile недостаточно, если процесс уже получил меньший системный лимит.
sudo systemctl edit nginx
[Service]
LimitNOFILE=131072
Затем примените override и перезапустите сервис:
sudo systemctl daemon-reload
sudo systemctl restart nginx
sudo nginx -t
sudo systemctl status nginx
Проверка пройдена, если nginx -t сообщает об успешной проверке, сервис находится в состоянии active (running), а новый лимит виден в файле /proc/ соответствующего worker-процесса.
Расчёт дескрипторов для прокси
Для обратного прокси используйте консервативную оценку: клиентский дескриптор плюс upstream-дескриптор, умноженные на число workers, с запасом под логи и служебные файлы. Если 50 тысяч клиентов одновременно обращаются к приложению, потенциальная потребность может быть близка к 100 тысячам сокетов, а не к 50 тысячам.
Реальное число upstream-соединений зависит от keep-alive, очередей запросов и настройки самого приложения. Не пытайтесь автоматически создать 50 тысяч соединений к бэкенду: это может исчерпать пул соединений базы данных или очередь приложения.
upstream application {
server 127.0.0.1:8080;
keepalive 64;
}
server {
listen 80;
server_name example.test;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_pass http://application;
}
}
Здесь keepalive 64 ограничивает число неактивных соединений каждого worker к upstream. Это не лимит клиентских соединений и не универсальное значение: если приложение медленное, маленький пул может увеличить ожидание, а большой — перегрузить бэкенд.
Как получить честные цифры до и после
Замеряйте не только среднее время ответа. Для 50 тысяч соединений важнее увидеть, где появляется очередь и сколько запросов заканчивается ошибкой.
- Зафиксируйте базу. Запишите версию Nginx, число CPU, объём RAM, тип диска, версию ядра, конфигурацию upstream и размер ответа. Проверьте конфигурацию командой
nginx -T. Результат — воспроизводимое описание стенда. - Проверьте лимиты. Посмотрите
worker_processes,worker_connections, лимит открытых файлов и backlog. Результат — вы знаете, является ли потолок конфигурационным, а не предполагаете это по графику CPU. - Разделите сценарии. Отдельно тестируйте короткие HTTP-запросы, долгий keep-alive и ответы большого размера. Результат — три профиля, а не одно среднее число, скрывающее проблему.
- Прогрейте тест. Не сравнивайте первые секунды после старта с прогретым состоянием. Дождитесь стабильного числа соединений и повторите каждый сценарий несколько раз. Результат — диапазон значений и p95 или p99, а не единственный удачный запуск.
- Снимите ошибки. Сверьте access log, error log, число активных соединений, RSS workers, CPU, retransmits и состояние upstream. Результат — понятно, выросла ли вместимость без скрытого переноса проблемы в приложение.
В отчёте оставьте колонки «до», «после», «разница» и «условия теста». Без одинаковых условий нельзя честно заявить, что настройка уменьшила задержку или увеличила пропускную способность.
Что ломается первым
Мало файловых дескрипторов
Признаки — сообщения too many open files, ошибки принятия новых соединений и резкий рост 5xx. Проверьте лимит процесса, systemd override и количество дескрипторов у worker. Увеличивать worker_connections без повышения лимита бессмысленно.
Слишком длинный keep-alive
Клиенты занимают слоты, хотя почти ничего не делают. Снижение тайм-аута освобождает ресурсы, но может увеличить число TCP-установок и TLS-handshake. Смотрите на задержку повторных запросов и CPU, а не только на количество открытых сокетов.
Узкое место в upstream
Nginx может принять десятки тысяч клиентов, пока приложение, база данных или пул соединений уже исчерпаны. В этом случае увеличение workers создаёт больше параллельной работы и ускоряет перегрузку. Ограничивайте upstream-пул по возможностям приложения и измеряйте очередь отдельно.
Слепое включение reuseport или multi_accept
Эти параметры способны изменить распределение новых соединений между workers, но не гарантируют снижение latency. На одной машине они могут помочь при перекосе, а на другой — увеличить конкуренцию за CPU. Добавляйте по одному параметру и оставляйте только результат, подтверждённый тестом.
Когда тюнинг Nginx не поможет
Если CPU занят шифрованием TLS, причина может быть в версии TLS, размере ключей, повторном использовании сессий или нехватке ядер. Если растёт время ответа приложения, Nginx не устранит блокировки в коде или медленные запросы к базе. Если сервер упирается в канал, увеличение worker_connections лишь позволит дольше накапливать очередь.
Не смешивайте настройку соединений с оптимизацией gzip, кешированием, HTTP/2 и HTTP/3. Это отдельные эксперименты с собственными метриками. Сначала добейтесь, чтобы сервер стабильно принимал заданное число соединений без ошибок, затем оптимизируйте стоимость одного запроса.
Что делать дальше
После изменения конфигурации поставьте наблюдение за активными соединениями, RSS каждого worker, p95 и p99 задержки, 4xx и 5xx, ошибками открытия файлов и состоянием upstream. Повторите тест после изменения размера ответа и доли keep-alive. Если цифры расходятся, ищите первое ограничение по графикам, а не добавляйте новые директивы вслепую.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: NGINX documentation: Core functionality, NGINX documentation: HTTP core module
Частые вопросы
Достаточно ли поставить worker_connections 65535 для 50 тысяч соединений?
Почему Nginx всё ещё не принимает соединения после увеличения лимита?
Нужно ли включать multi_accept для высокой нагрузки?
Что изменится, если у меня Nginx другой версии?
Можно ли измерить эффект на одном показателе RPS?
Что делать, если после настройки выросло потребление памяти?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.