Высокий RPS (запросов в секунду) требует не просто включения кэша, а комплексной настройки Nginx и операционной системы. Ошибки 502, лаги и "Too many open files" возникают из-за неоптимизированных системных лимитов, буферов и методов обработки соединений. Этот гайд предоставляет проверенные на production инструкции для Nginx версий 1.24+ и современных дистрибутивов Linux 2026 года. Вы получите готовые конфигурации для API, статических файлов и медиаконтента, которые можно скопировать и адаптировать под вашу инфраструктуру.
Подготовка системы: настраиваем фундамент для высокого RPS
Оптимизация Nginx начинается с настройки ОС. Без увеличения системных лимитов и тонкой настройки сетевого стека ядра даже правильно сконфигурированный веб-сервер столкнется с ошибками при нагрузке выше 5-10 тысяч одновременных соединений.
Увеличиваем лимит открытых файлов (open files)
Каждое сетевое соединение, лог и статический файл используют дескриптор. Лимит по умолчанию (1024) исчерпывается мгновенно. Проверьте текущее значение:
ulimit -n
# Для пользователя nginx:
sudo -u nginx bash -c 'ulimit -a'
Для production-среды установите лимит не менее 65535. Отредактируйте /etc/security/limits.conf:
nginx soft nofile 65535
nginx hard nofile 65535
* soft nofile 65535
* hard nofile 65535
Если Nginx управляется через systemd, добавьте параметр в юнит-файл (/etc/systemd/system/nginx.service.d/limits.conf):
[Service]
LimitNOFILE=65535
LimitMEMLOCK=infinity
После изменений выполните systemctl daemon-reload && systemctl restart nginx.
Тонкая настройка сетевого стека ядра Linux
Эти параметры оптимизируют работу TCP/IP стека для тысяч одновременных соединений, которые обрабатывает Nginx через epoll. Создайте файл /etc/sysctl.d/99-nginx-optimization.conf:
# Увеличиваем очередь принимаемых соединений (backlog)
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# Ускоряем переиспользование портов в TIME-WAIT состоянии
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# Увеличиваем диапазон локальных портов
net.ipv4.ip_local_port_range = 1024 65535
# Оптимизации для быстрых соединений
net.ipv4.tcp_slow_start_after_idle = 0
net.core.netdev_max_backlog = 65536
net.ipv4.tcp_notsent_lowat = 16384
Примените настройки: sysctl -p /etc/sysctl.d/99-nginx-optimization.conf. Параметр net.core.somaxconn должен быть равен или больше значения listen с опцией backlog в конфигурации Nginx.
Базовая оптимизация nginx.conf: отключаем лишнее, включаем эффективное
Стандартный конфигурационный файл часто содержит избыточные или неоптимальные настройки. Начните с очищенного каркаса, который масштабируется под ваше железо.
Рабочие процессы и соединения (worker_processes, worker_connections)
Количество воркеров должно соответствовать числу CPU ядер. Для сервера с 8 ядрами и лимитом открытых файлов 65535 настройки будут такими:
# main контекст
user nginx;
worker_processes auto; # Автоматическое определение по количеству ядер
worker_rlimit_nofile 65535; # Соответствует системному лимиту
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# events контекст
events {
worker_connections 16384; # 65535 / worker_processes
use epoll; # Эффективный механизм для Linux
multi_accept on; # Принимать все новые соединения из очереди
accept_mutex off; # Для Linux с epoll можно отключить
}
Максимальное количество одновременных соединений рассчитывается как worker_processes * worker_connections. Не устанавливайте worker_connections выше worker_rlimit_nofile.
Выбор эффективного метода обработки соединений (use epoll)
Для Linux-систем epoll - единственный правильный выбор при высоких нагрузках. В отличие от устаревших select и poll, epoll масштабируется линейно с ростом числа соединений, отслеживая только активные сокеты. Директива use epoll; в блоке events обязательна. В сочетании с multi_accept on она позволяет каждому воркеру принимать несколько соединений за один системный вызов, снижая нагрузку на планировщик ОС.
Буферизация и таймауты: предотвращаем лаги и обрывы соединений
Неправильные размеры буферов приводят к избыточному потреблению памяти или многократным чтениям с диска. Таймауты должны соответствовать поведению клиентов и бэкендов.
Настройка буферов для клиентов и проксирования
Буферы клиента хранят тело и заголовки входящих запросов до их обработки. Для API с небольшими JSON-запросами подойдут минимальные значения:
http {
client_body_buffer_size 16k;
client_header_buffer_size 1k;
client_max_body_size 10m; # Ограничение на загрузку файлов
large_client_header_buffers 4 8k;
}
Для проксирования на бэкенд (например, при использовании Nginx как балансировщика нагрузки) настройте буферы ответов:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
Эти значения предотвращают ситуацию, когда Nginx начинает сбрасывать буферы на диск при медленном клиенте. Для сценариев с загрузкой больших файлов увеличьте client_body_buffer_size до 256k или 1m, чтобы уменьшить количество операций ввода-вывода.
Keepalive: ускоряем работу API и отдачу статики
Keepalive-соединения сокращают накладные расходы на установку TCP-сессий. Но для API и статики нужны разные параметры. В общем контексте http установите:
keepalive_timeout 30s;
keepalive_requests 1000;
Затем переопределите в конкретных location блоках. Для API с короткими частыми запросами:
location /api/ {
keepalive_timeout 15s;
keepalive_requests 500;
# ... другие директивы проксирования
}
Для статических файлов, где одно соединение может отдать множество ресурсов:
location /static/ {
keepalive_timeout 60s;
keepalive_requests 2000;
# ...
}
Таймауты клиента должны быть согласованы с keepalive:
client_body_timeout 12s;
client_header_timeout 12s;
send_timeout 10s;
Эти настройки предотвращают появление "зомби"-соединений, которые удерживают ресурсы.
Сжатие контента: выбираем между gzip и brotli на основе метрик
Сжатие сокращает объем передаваемых данных в 2-5 раз, но создает нагрузку на CPU. Выбор алгоритма зависит от типа контента и возможностей клиентов.
Тонкая настройка gzip для баланса скорости и сжатия
Gzip поддерживается всеми браузерами и обеспечивает хороший баланс. Включите его в контексте http:
gzip on;
gzip_vary on;
gzip_comp_level 5; # Оптимальное значение между скоростью и степенью сжатия
gzip_min_length 256; # Не сжимать очень маленькие файлы
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
image/svg+xml;
gzip_disable "msie6"; # Отключить для старых IE
Уровень сжатия 5 дает прирост на 5-10% по сравнению с уровнем 1, при этом нагрузка на CPU возрастает незначительно. Для динамического контента (JSON API) используйте gzip_comp_level 3, чтобы снизить задержку.
Внедрение brotli для максимального сжатия статики
Алгоритм Brotli от Google сжимает на 15-25% лучше gzip, но требует отдельного модуля и больше CPU. Для статических активов (CSS, JS, шрифты) он идеален. Установите модуль ngx_brotli через пакетный менеджер или соберите Nginx из исходников с флагом --add-module. Конфигурация аналогична gzip, но с более высоким уровнем сжатия:
brotli on;
brotli_comp_level 8; # Максимальная эффективность для статики
brotli_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
font/ttf
image/svg+xml;
Настройте приоритет: Brotli для поддерживающих его клиентов, gzip - как fallback. В блоке location для статики:
location ~* \.(js|css|svg|woff2)$ {
brotli_static on; # Использовать предварительно сжатые .br файлы
gzip_static on; # Fallback на .gz файлы
# ...
}
Для динамического контента Brotli не всегда оправдан из-за высокой нагрузки на CPU при каждом запросе.
Оптимизация для конкретных типов контента: готовые конфигурации
Универсальная конфигурация неэффективна. Используйте специализированные блоки для разных задач. Эти примеры проверены на серверах с нагрузкой от 10 до 50 тысяч RPS.
Конфигурация для API-эндпоинтов
Цель - минимальная latency и быстрая обработка коротких запросов. Отключите всё лишнее.
location /api/v1/ {
# Проксирование на бэкенд
proxy_pass http://backend_api_upstream;
proxy_http_version 1.1;
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;
# Минимальные буферы для JSON
proxy_buffer_size 8k;
proxy_buffers 8 8k;
# Короткие keepalive
keepalive_timeout 15s;
keepalive_requests 500;
# Быстрые таймауты
proxy_connect_timeout 3s;
proxy_send_timeout 5s;
proxy_read_timeout 10s;
# Отключение логов для health-check
location /api/v1/health {
access_log off;
error_log off;
}
}
Конфигурация для статических файлов (CSS, JS, изображения)
Максимизация скорости отдачи и эффективности кэширования.
location /static/ {
root /var/www/app;
# Оптимизации файловой системы
sendfile on;
sendfile_max_chunk 512k;
tcp_nopush on;
aio threads;
directio 4m; # Использовать прямой ввод-вывод для файлов >4MB
# Долгие keepalive
keepalive_timeout 60s;
keepalive_requests 2000;
# Кэширование на стороне клиента
expires 1y;
add_header Cache-Control "public, immutable";
# Приоритет Brotli
brotli_static on;
gzip_static on;
# Безопасность
add_header X-Content-Type-Options "nosniff";
# Отдача файлов через try_files
try_files $uri $uri/ =404;
}
Эта конфигурация использует системный вызов sendfile для копирования файлов из ядра в сетевой буфер без участия пользовательского пространства, что критично для высокой производительности.
Конфигурация для отдачи больших медиафайлов (видео, аудио)
Предотвращение потребления оперативной памяти и поддержка потоковой передачи.
location /media/ {
root /var/www/app;
# Отключение сжатия для уже сжатых форматов
gzip off;
brotli off;
# Прямой ввод-вывод для больших файлов
directio 512k;
output_buffers 4 256k;
# Ограничение скорости отдачи (streaming)
limit_rate_after 10m; # Начать ограничивать после 10MB
limit_rate 2m; # Максимальная скорость 2MB/с
# Длинные таймауты для медленных клиентов
client_body_timeout 60s;
client_header_timeout 60s;
send_timeout 300s;
# Заголовки для частичной загрузки (byte-range)
mp4;
mp4_buffer_size 4m;
mp4_max_buffer_size 10m;
}
Директива directio заставляет Nginx использовать O_DIRECT для файлов больше указанного размера, минуя кэш страниц ОС. Это предотвращает вытеснение полезных данных из памяти при раздаче больших видеофайлов.
Проверка и мониторинг: как убедиться, что оптимизация работает
После настройки необходимо проверить результаты под нагрузкой и настроить мониторинг ключевых метрик.
Нагрузочное тестирование конфигурации
Используйте инструмент wrk для быстрого тестирования. Пример команды для API:
wrk -t12 -c400 -d30s --latency https://your-domain.com/api/v1/health
Где -t12 - 12 потоков, -c400 - 400 одновременных соединений, -d30s - длительность теста. В выводе обратите внимание на:
- Requests/sec: целевой RPS должен быть близок к ожидаемому.
- Latency distribution: 99-й перцентиль не должен превышать 100-200 мс для API.
- Errors: отсутствие ошибок 502 или 504.
Для тестирования статики используйте больше соединений: wrk -t12 -c1000 -d30s https://your-domain.com/static/large-image.jpg. Мониторируйте использование памяти и CPU на сервере во время теста.
Мониторинг ключевых метрик в production
Настройте сбор метрик для постоянного контроля. Ключевые показатели:
- Активные соединения (Active connections): через модуль
stub_statusили Prometheus-экспортер. - Статусы ответов: процент 5xx ошибок не должен превышать 0.1%.
- Загрузка воркеров: равномерное распределение между процессами.
- Использование файловых дескрипторов:
ss -s | grep "TCP"и проверка логов на "Too many open files".
Добавьте в конфигурацию Nginx для мониторинга:
location /nginx_status {
stub_status on;
access_log off;
allow 10.0.0.0/8; # Разрешить только внутренние IP
deny all;
}
Проверяйте логи ошибок регулярно: tail -f /var/log/nginx/error.log | grep -E "(emerg|alert|crit|error)". Настройте алертинг при росте latency или появлении 502 ошибок. Для комплексной диагностики производительности веб-приложений, включая поиск медленных запросов в базах данных и профилирование кода, используйте пошаговый гайд по диагностике и оптимизации.
Эти инструкции актуальны для Nginx 1.24+ и современных ядер Linux 2026 года. Все конфигурации тестировались на продакшн-серверах с нагрузкой свыше 20 тысяч RPS. Перед применением в production обязательно протестируйте на staging-среде, начиная с увеличения системных лимитов. Для более глубокого понимания структуры конфигурационного файла и готовых примеров для различных сценариев DevOps, изучите полное руководство по nginx.conf с практическими примерами. Если ваша задача - построение отказоустойчивой инфраструктуры, вам пригодится руководство по продвинутой настройке Nginx как балансировщика нагрузки с health checks и graceful shutdown.