Основной чек-лист по настройке производительности Nginx для высоконагруженных сайтов
Практический чек-лист по производительности Nginx: рабочие процессы, соединения, буферы, кэширование, сжатие, журналы, тайм-ауты, TLS и статические файлы.
Основной чек-лист по настройке производительности Nginx для высоконагруженных сайтов
Настройка производительности Nginx проще всего, когда вы относитесь к этому как к чек-листу, а не как к угадыванию. Начните с лимитов, которые определяют, сколько трафика может принять Nginx, затем переходите к буферизации, кэшированию, сжатию, ведению журналов, тайм-аутам, TLS и серверным службам, стоящим за ним.
Не вставляйте все эти директивы в продакшн сразу. Хороший чек-лист по настройке производительности Nginx помогает решить, что проверить, почему это важно и что может пойти не так, если переусердствовать. Правильная настройка для в основном статического сайта документации не подходит для API с длинными опросами или службы загрузки файлов.
1. Оптимизация рабочих процессов и соединений
Nginx использует модель процессов «мастер-воркер». Мастер-процесс читает конфигурацию и управляет рабочими процессами, которые обрабатывают фактические запросы клиентов. Правильная настройка этих параметров может значительно улучшить параллелизм и использование ресурсов.
worker_processes
Эта директива определяет, сколько рабочих процессов будет порождать Nginx. Обычно установка значения auto позволяет Nginx определить количество ядер ЦП и породить равное количество рабочих процессов, что является распространённой лучшей практикой.
worker_connections
Определяет максимальное количество одновременных соединений, которое может открыть один рабочий процесс. Этот параметр в сочетании с worker_processes определяет общее теоретическое количество одновременных соединений, которое может обработать Nginx (worker_processes * worker_connections).
multi_accept
Позволяет рабочему процессу принимать несколько новых соединений одновременно, предотвращая потенциальные узкие места при высокой нагрузке.
# /etc/nginx/nginx.conf
worker_processes auto; # Обычно устанавливается в 'auto' или количество ядер ЦП
events {
worker_connections 1024; # Настройте в зависимости от ёмкости сервера и ожидаемой нагрузки
multi_accept on;
}
Совет: Если загрузка ЦП постоянно высока, увеличение
worker_connectionsсамо по себе не решит проблему. Сначала определите, вызвана ли загрузка ЦП рукопожатиями TLS, сжатием, ведением журналов, маршрутизацией с большим количеством регулярных выражений или вышестоящим приложением.
2. Эффективное управление соединениями
Оптимизация того, как Nginx обрабатывает сетевые соединения, может снизить накладные расходы и повысить отзывчивость.
keepalive_timeout
Указывает, как долго будет оставаться открытым keep-alive соединение с клиентом. Повторное использование соединений снижает накладные расходы на установку новых TCP-соединений и рукопожатий SSL. Обычное значение — 15-65 секунд, в зависимости от интерактивности вашего приложения.
sendfile
Включает прямую передачу данных между файловыми дескрипторами, минуя буферизацию в пользовательском пространстве. Это значительно повышает производительность при обслуживании статических файлов.
tcp_nopush
Работает вместе с sendfile. Nginx пытается отправить HTTP-заголовок и начало файла в одном пакете. После этого он отправляет данные полными пакетами. Это уменьшает количество отправляемых пакетов.
tcp_nodelay
Указывает Nginx отправлять данные сразу, как только они становятся доступны, без буферизации. Это полезно для интерактивных приложений, где низкая задержка важнее максимальной пропускной способности (например, чаты или обновления в реальном времени).
http {
keepalive_timeout 65; # Keep-alive соединения на 65 секунд
sendfile on;
tcp_nopush on; # Требует sendfile on
tcp_nodelay on; # Полезно для проксирования динамического контента
}
3. Оптимизация буферов
Nginx использует буферы для обработки запросов клиентов и ответов от вышестоящих серверов (например, серверов приложений). Правильный размер этих буферов может предотвратить ненужный ввод-вывод на диск, уменьшить использование памяти и повысить пропускную способность.
Буферы клиента
client_body_buffer_size: Размер буфера для тела запроса клиента. Если тело превышает этот размер, оно записывается во временный файл.client_header_buffer_size: Размер буфера для первой строки и заголовков запроса клиента.large_client_header_buffers: Определяет количество и размер больших буферов для чтения заголовков запросов клиентов. Полезно для запросов с большим количеством куки или длинными заголовками referer.
Буферы прокси (для настройки обратного прокси)
proxy_buffers: Количество и размер буферов, используемых для чтения ответов от проксируемого сервера.proxy_buffer_size: Размер первого буфера для чтения ответа. Обычно меньше, так как часто содержит только заголовки.proxy_busy_buffers_size: Максимальный объём буферов ответов, которые могут находиться в состоянии «занято» (активно отправляются клиенту) в любой момент времени.
Буферы FastCGI (для PHP-FPM и т.д.)
fastcgi_buffers: Количество и размер буферов, используемых для чтения ответов от сервера FastCGI.fastcgi_buffer_size: Размер первого буфера для чтения ответа.
http {
# Буферы клиента
client_body_buffer_size 1M; # Настройте в зависимости от ожидаемого размера тела запроса (например, загрузка файлов)
client_header_buffer_size 1k;
large_client_header_buffers 4 8k; # 4 буфера, каждый по 8 КБ
# Буферы прокси (если Nginx выступает в роли обратного прокси)
proxy_buffers 8 16k; # 8 буферов, каждый по 16 КБ
proxy_buffer_size 16k; # Первый буфер 16 КБ
proxy_busy_buffers_size 16k; # Макс. 16 КБ занятых буферов
# Буферы FastCGI (если Nginx работает с PHP-FPM)
fastcgi_buffers 16 16k; # Отправная точка для многих приложений PHP-FPM
fastcgi_buffer_size 16k; # Первый буфер 16 КБ
}
Предупреждение: Слишком маленькие буферы могут привести к вводу-выводу на диск и снижению производительности. Слишком большие буферы могут потреблять чрезмерный объём памяти. Найдите баланс с помощью тестирования.
4. Внедрение надёжных стратегий кэширования
Кэширование — один из наиболее эффективных способов повышения производительности и снижения нагрузки на ваши серверы. Nginx может выступать в роли мощного кэша контента.
proxy_cache_path
Определяет путь к каталогу кэша, его размер, количество уровней подкаталогов и время хранения неактивных элементов в кэше.
proxy_cache
Активирует кэширование для данного блока location, ссылаясь на зону, определённую в proxy_cache_path.
proxy_cache_valid
Устанавливает время, в течение которого Nginx должен кэшировать ответы с определёнными кодами состояния HTTP.
proxy_cache_revalidate
При включении Nginx будет использовать заголовки If-Modified-Since и If-None-Match для повторной проверки кэшированного контента на сервере, уменьшая использование пропускной способности.
proxy_cache_use_stale
Указывает Nginx обслуживать устаревший кэшированный контент, если сервер не работает, не отвечает или испытывает ошибки. Это значительно повышает доступность.
expires
Устанавливает заголовки Cache-Control и Expires для кэширования статических файлов на стороне клиента. Это минимизирует повторные запросы к Nginx.
http {
# Определите зону прокси-кэша в блоке http
proxy_cache_path /var/cache/nginx/my_cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=10g;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://my_upstream_backend;
proxy_cache my_cache; # Включить кэширование для этого location
proxy_cache_valid 200 302 10m; # Кэшировать успешные ответы на 10 минут
proxy_cache_valid 404 1m; # Кэшировать 404 на 1 минуту
proxy_cache_revalidate on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status; # Помогает с отладкой
}
# Кэшировать статические файлы в браузере на более длительный срок
location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
expires 30d; # Кэшировать на 30 дней
add_header Cache-Control "public, no-transform";
# Для статических файлов рассмотрите возможность прямой отдачи из Nginx, если они не проксируются
root /var/www/html;
}
}
}
5. Включение сжатия Gzip
Сжатие ответов перед отправкой клиентам может значительно снизить использование пропускной способности и улучшить время загрузки страниц, особенно для текстового контента.
gzip on
Активирует сжатие gzip.
gzip_comp_level
Устанавливает уровень сжатия (1-9). Уровень 1 — самый быстрый с наименьшим сжатием; Уровень 9 — самый медленный с максимальным сжатием. Уровень 6 обычно обеспечивает хороший баланс.
gzip_types
Указывает типы MIME, которые должны быть сжаты. Включите распространённые типы текста, CSS, JavaScript и JSON.
gzip_min_length
Устанавливает минимальную длину ответа (в байтах), для которого должно быть включено сжатие. Маленькие файлы не получают большой выгоды и могут даже замедляться из-за накладных расходов на сжатие.
gzip_proxied
Указывает Nginx сжимать ответы, даже если они проксируются. any — распространённое значение.
gzip_vary
Добавляет заголовок Vary: Accept-Encoding к ответам, информируя прокси-серверы о том, что ответ может различаться в зависимости от заголовка запроса Accept-Encoding.
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6; # Уровень сжатия 1-9 (6 — хороший баланс)
gzip_buffers 16 8k; # 16 буферов, каждый по 8 КБ
gzip_http_version 1.1; # Минимальная версия HTTP для сжатия
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_min_length 1000; # Сжимать только ответы размером более 1 КБ
}
6. Оптимизация ведения журналов
Хотя журналы необходимы для мониторинга и устранения неполадок, чрезмерное или неоптимизированное ведение журналов может привести к значительному вводу-выводу на диск, особенно на сайтах с высокой посещаемостью.
access_log
- Отключите для статических ресурсов: Для часто запрашиваемого статического контента (изображения, CSS, JS) отключение
access_logможет сэкономить много операций ввода-вывода. - Буферизация: Nginx может буферизовать записи журнала в памяти перед записью на диск, уменьшая частоту операций записи на диск. Здесь используются параметры
bufferиflush.
error_log
Установите соответствующий уровень ведения журнала (crit, error, warn, info, debug). Для продакшена обычно достаточно warn или error, чтобы фиксировать критические проблемы без переполнения журналов.
http {
server {
# Журнал доступа по умолчанию для динамического контента
access_log /var/log/nginx/access.log main;
location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
access_log off; # Отключить ведение журнала для распространённых статических файлов
expires 30d;
}
}
# Пример буферизованного журнала доступа для основного контекста HTTP
# access_log /var/log/nginx/access.log main buffer=16k flush=5s;
error_log /var/log/nginx/error.log warn; # Логировать только предупреждения и выше
}
7. Настройка тайм-аутов
Правильно настроенные тайм-ауты предотвращают удержание неактивных соединений Nginx слишком долго, освобождая ресурсы.
Тайм-ауты на стороне клиента
client_body_timeout: Как долго Nginx ждёт, пока клиент отправит тело запроса.client_header_timeout: Как долго Nginx ждёт, пока клиент отправит заголовок запроса.send_timeout: Как долго Nginx ждёт, пока клиент примет ответ после его отправки.
Тайм-ауты прокси/FastCGI (если применимо)
proxy_connect_timeout: Тайм-аут для установки соединения с проксируемым сервером.proxy_send_timeout: Тайм-аут для передачи запроса на проксируемый сервер.proxy_read_timeout: Тайм-аут для чтения ответа от проксируемого сервера.
http {
client_body_timeout 15s; # У клиента есть 15 секунд для отправки тела
client_header_timeout 15s; # У клиента есть 15 секунд для отправки заголовков
send_timeout 15s; # У Nginx есть 15 секунд для отправки ответа клиенту
# Для сценариев прокси
proxy_connect_timeout 5s; # 5 секунд для подключения к вышестоящему серверу
proxy_send_timeout 15s; # 15 секунд для отправки запроса вышестоящему серверу
proxy_read_timeout 15s; # 15 секунд для чтения ответа от вышестоящего сервера
# Для сценариев FastCGI
fastcgi_connect_timeout 5s;
fastcgi_send_timeout 15s;
fastcgi_read_timeout 15s;
}
8. Оптимизация SSL/TLS
Для сайтов с поддержкой HTTPS оптимизация настроек SSL/TLS имеет решающее значение для снижения нагрузки на ЦП и повышения производительности рукопожатий.
ssl_session_cache и ssl_session_timeout
Включите кэширование сеансов SSL, чтобы избежать дорогостоящего полного рукопожатия TLS для последующих соединений от того же клиента.
ssl_protocols и ssl_ciphers
Используйте современные протоколы TLS, такие как TLSv1.2 и TLSv1.3. Будьте осторожны со скопированными строками шифров: шифры TLS 1.3 управляются иначе, чем старые наборы шифров TLS, и настройки по умолчанию в дистрибутиве часто безопаснее, чем устаревшие примеры из старых руководств.
ssl_stapling
Включает OCSP stapling, при котором Nginx периодически получает ответ OCSP от ЦС и «скрепляет» его с рукопожатием SSL/TLS. Это снижает задержку на стороне клиента, избегая отдельного запроса OCSP.
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/your_domain.crt;
ssl_certificate_key /etc/nginx/ssl/your_domain.key;
ssl_session_cache shared:SSL:10m; # Общий кэш для 10 МБ данных сеанса
ssl_session_timeout 10m; # Сеансы истекают через 10 минут
ssl_protocols TLSv1.2 TLSv1.3; # Используйте современные, безопасные протоколы
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s; # Используйте резолверы, одобренные для вашего окружения
resolver_timeout 5s;
}
9. Кэш открытых файлов
Nginx может кэшировать файловые дескрипторы для часто запрашиваемых файлов, уменьшая потребность в повторных системных вызовах для открытия и закрытия файлов.
open_file_cache
Включает кэш, указывая максимальное количество элементов и время хранения неактивных элементов.
open_file_cache_valid
Устанавливает, как часто кэш должен проверять действительность своих элементов.
open_file_cache_min_uses
Указывает минимальное количество раз, которое файл должен быть запрошен в течение времени inactive, чтобы оставаться в кэше.
open_file_cache_errors
Определяет, должен ли Nginx кэшировать ошибки при открытии файлов.
http {
open_file_cache max=100000 inactive=60s; # Кэшировать до 100 000 файловых дескрипторов на 60 секунд
open_file_cache_valid 80s; # Проверять действительность каждые 80 секунд
open_file_cache_min_uses 1; # Кэшировать файлы, использованные хотя бы один раз
open_file_cache_errors on; # Кэшировать ошибки, связанные с открытием файлов
}
10. Проверка с помощью реальных сигналов трафика
Последний пункт в чек-листе — измерение. Перед изменением зафиксируйте небольшой базовый уровень: задержку запроса, частоту ошибок 5xx, активные соединения, ЦП, память, ввод-вывод на диск, пропускную способность сети и время ответа вышестоящего сервера. После изменения сравните те же показатели.
Для обратного прокси особенно полезны $request_time и $upstream_response_time. Если оба растут вместе, вероятно, медленный сервер. Если $request_time высок, а время вышестоящего сервера низкое или пустое, обратите внимание на скорость загрузки клиента, время передачи ответа, буферизацию, сжатие или доставку статических файлов. Если ни один показатель не объясняет проблему, проверьте журнал ошибок и операционную систему.
Самая безопасная последовательность настройки проста: проверьте конфигурацию с помощью nginx -t, перезагружайте вместо перезапуска, когда это возможно, следите за журналами и быстро откатывайте изменения, если задержка или ошибки движутся в неправильном направлении. Nginx может обрабатывать много трафика, но только когда его лимиты, ядро и вышестоящее приложение согласованы друг с другом.