Загрузка...
Загрузка...
Тюнинг производительности Nginx: worker processes, gzip/brotli, кэширование, буферы, keepalive, rate limiting, балансировка нагрузки.
Полное руководство по настройке Brotli сжатия на веб-серверах: Nginx, Apache, сравнение с Gzip, уровни сжатия и проверка работы.
ПроизводительностьПолное руководство по кэшированию в веб-разработке. HTTP-кэширование, Service Workers, CDN, кэширование на сервере и в базе данных. Практические стратегии для ускорения сайтов.
БезопасностьНастройка HTTP-кэширования: Cache-Control, ETag, Last-Modified, stale-while-revalidate. Стратегии для статики, HTML и API. Примеры для Nginx и Node.js.
SEOПолное руководство по оптимизации Largest Contentful Paint. Причины медленного LCP, методы диагностики, практические решения для изображений, шрифтов и серверной инфраструктуры.
Поделитесь с коллегами или изучите другие материалы блога
Nginx известен высокой производительностью, но «из коробки» он настроен на средние нагрузки. Для высоконагруженных проектов нужна тонкая настройка: worker processes, сжатие, кэширование, буферы, keepalive и ограничение запросов. В статье разобраны практические параметры и примеры конфигурации. Сгенерировать базовый конфиг можно в Nginx Generator на reChecker. Проверить HTTP/2 и Brotli — через HTTP/2 Checker, метрики загрузки — в Web Vitals.
Базовая настройка процессов и соединений задаётся в nginx.conf:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
auto — по числу ядер CPU (рекомендуется)Максимум одновременных соединений на один worker. Итоговая пропускная способность: worker_processes × worker_connections. Для 4 ядер и 4096 соединений — до 16384 одновременных соединений.
Лимит открытых файловых дескрипторов. Должен быть не меньше worker_connections. На Linux проверьте ulimit -n и при необходимости увеличьте в systemd или /etc/security/limits.conf.
При on worker принимает все новые соединения из очереди за один вызов. Снижает задержки при всплесках трафика.
Механизм мультиплексирования. epoll — для Linux, kqueue — для FreeBSD/macOS. На современных системах обычно определяется автоматически.
Сжатие снижает объём передаваемых данных и ускоряет загрузку страниц.
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
application/rss+xml
image/svg+xml;
Параметры:
gzip_comp_level 5 — компромисс скорость/степень сжатия (1–9)gzip_min_length 256 — не сжимать файлы меньше 256 байтgzip_proxied any — сжимать ответы от upstream даже при заголовках X-Accel-ExpiresBrotli даёт лучшее сжатие, чем gzip, но требует отдельного модуля:
# Ubuntu: модуль из репозитория
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript;
Проверить поддержку Brotli можно через HTTP/2 & Brotli Checker.
location ~* \.(jpg|jpeg|png|gif|ico|webp|avif|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
location ~* \.(css|js)$ {
expires 30d;
add_header Cache-Control "public";
access_log off;
}
location ~* \.(woff2?|ttf|otf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
immutable — браузер не будет повторно проверять ресурс до истечения срока. Подходит для файлов с хешем в имени (например, main.a1b2c3.js).
Для ответов от backend:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
location / {
proxy_pass http://backend;
proxy_cache app_cache;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
}
}
Параметры:
keys_zone=app_cache:10m — 10 МБ под ключи кэшаmax_size=1g — максимум 1 ГБ на дискеinactive=60m — удаление неиспользуемых записей через 60 минутproxy_cache_use_stale — отдавать устаревший кэш при ошибках backendproxy_cache_lock — один запрос обновляет кэш, остальные ждутproxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 16k;
При большом ответе от backend Nginx буферизует его. Недостаточный размер буферов приводит к записи во временные файлы и росту I/O.
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
Для долгих операций (загрузка файлов, long polling) увеличьте proxy_read_timeout.
client_body_buffer_size 16k;
client_header_buffer_size 1k;
client_max_body_size 10m;
large_client_header_buffers 4 8k;
client_max_body_size — лимит размера тела запроса (загрузки). По умолчанию 1 МБ.
Постоянные соединения к backend снижают накладные расходы на TCP/TLS handshake:
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
proxy_http_version 1.1 и Connection "" обязательны для keepalive. keepalive 32 — пул из 32 соединений на каждый worker.
Защита от перегрузки и DDoS:
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn:10m;
server {
location / {
limit_req zone=general burst=20 nodelay;
limit_conn conn 10;
# ...
}
location /login {
limit_req zone=login burst=5 nodelay;
# ...
}
}
rate=10r/s — 10 запросов в секунду с одного IPburst=20 — допускается кратковременный всплеск до 20 запросовnodelay — обрабатывать burst без задержки (иначе лишние запросы откладываются)limit_conn conn 10 — не более 10 одновременных соединений с одного IPupstream backend {
server 192.168.1.10:80;
server 192.168.1.11:80;
server 192.168.1.12:80;
}
upstream backend {
server 192.168.1.10:80 weight=3;
server 192.168.1.11:80 weight=2;
server 192.168.1.12:80 weight=1;
}
upstream backend {
least_conn;
server 192.168.1.10:80;
server 192.168.1.11:80;
}
upstream backend {
ip_hash;
server 192.168.1.10:80;
server 192.168.1.11:80;
}
Один и тот же клиент всегда идёт на один и тот же backend.
В open source Nginx нет встроенных health checks. Используйте max_fails и fail_timeout:
upstream backend {
server 192.168.1.10:80 max_fails=3 fail_timeout=30s;
server 192.168.1.11:80 max_fails=3 fail_timeout=30s;
}
После 3 неудачных попыток сервер исключается на 30 секунд.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
sendfile передаёт файлы напрямую из ядра, без копирования в user space. tcp_nopush отправляет пакеты полными. tcp_nodelay отключает алгоритм Нейгла для быстрой отдачи мелких ответов.
Кэширование дескрипторов открытых файлов:
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_buffer_size 4k;
ssl_buffer_size 4k уменьшает размер первого TLS-пакета и может снизить задержку (TLS 1.3).
На высоконагруженных сайтах логи создают значительную нагрузку:
# Отключить access_log для статики
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
access_log off;
# ...
}
# Буферизация логов
access_log /var/log/nginx/access.log combined buffer=64k flush=5s;
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
# File cache
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn:10m;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
После изменений проверяйте:
top, htopss -s, netstatПодробнее о структуре конфигурации — в руководстве по Nginx. Настройка SSL и TLS — в статье про SSL в Nginx.