Создание, продвижение сайтов
40-33-54

Ускоряем Nginx за 5 минут

16 декабря 2019

Как правило, настроенный должным образом сервер Nginx на Linux, может обрабатывать 500,000 — 600,000 запросов в секунду. Но этот показатель можно весьма ощутимо увеличить. Хотел бы обратить внимание на тот факт, что настройки, описанные ниже, применялись в тестовой среде и, возможно, для ваших боевых серверов они не подойдут.

 

yum -y install nginx 

Создадим бэкап исходного конфига.
 


 
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig vim /etc/nginx/nginx.conf 

Начнём с директивы worker_processes. Если Nginx выполняет работу нагружающую процессор (например SSL или gzipping), то оптимально установить эту директиву в значение, равное количеству ядер процессора. Выигрыш при большем значении вы получите только в случае обработки очень большого количества статики.
 


 
# This number should be, at maximum, the number of CPU cores on your system. worker_processes 24; 

Также, директива worker_processes, умноженная на worker_connections из секции event, даст максимально возможное количество клиентов.
 


 
# Determines how many clients will be served by each worker process. worker_connections 4000; 

Тема, которую я хочу затронуть — это worker_rlimit_nofile. Данная директива указывает, сколько файловых дескрипторов будет использовать Nginx. На каждое соединение надо выделять по два дексриптора, даже для статических файлов (картинки/JS/CSS): один для соединения с клиентом, а второй — для открытия статического файла. Таким образом, значение worker_rlimit_nofile должно быть равным удвоенному значению Max Clients. В системе это значение можно установить из командной строки ulimit -n 200000 или используя /etc/security/limits.conf.
 


 
# Number of file descriptors used for Nginx. worker_rlimit_nofile 200000; 

Теперь разберёмся с логированием. Во-первых, оставим логирование только критических ошибок.
 


 
# Only log critical errors. error_log /var/log/nginx/error.log crit 

Помните, что error_log off вам не поможет. Вы просто получите весь лог в файле off. Для отключения логирования ошибок надо делать так:
 


 
# Fully disable log errors. error_log /dev/null crit; 

А вот логи доступа не так страшно отключить полностью.
 


 
# Disable access log altogether. access_log off; 

Или, хотя бы, включить буфер чтения / записи.
 


 
# Buffer log writes to speed up IO. access_log /var/log/nginx/access.log main buffer=16k; 

Для обработки подключений Nginx поддерживает ряд методов. Наиболее эффективным для Linux является метод epoll.
 


 
# The effective method, used on Linux 2.6+, optmized to serve many clients with each thread. use epoll; 

Для того, чтобы Nginx пытался принять максимальное количество подключений, необходимо включить директиву multi_accept. Однако при слишком маленьком значении worker_connections, их лимит может быть очень быстро исчерпан.
 


 
# Accept as many connections as possible, after nginx gets notification about a new connection. multi_accept on; 

Конечно же, нам не обойтись без кеширования информации о:

  • дескрипторах недавно открытых файлов: их размера и даты модификации;
  • существовании директорий;
  • ошибках при поиске файлов: отсутствие самого файла, отсутствие прав на чтение и т.д.

Советую не копировать значения директив кеширования, а поиграть с ними, подобрав оптимальные для вашего окружения.
 


 
# Caches information about open FDs, freqently accessed files. open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; 

Директива sendfile активирует копирование данных между файловыми дескрипторами средствами ядра, что намного эффективнее связки read() + write(), которая требует обмена данными с пользовательским пространством.
 


 
# Sendfile copies data between one FD and other from within the kernel. sendfile on; 

После включения sendfile, можно заставить Nginx отправлять заголовки HTTP-ответов одним пакетом, а не отдельным частями.
 


 
# Causes nginx to attempt to send its HTTP response head in one packet, instead of using partial frames. tcp_nopush on; 

Для keep-alive подключений можно выключить буферизацию (алгоритм Нейгла). Это будет полезно при частом запросе маленьких объёмов данных в режиме реального времени, без получения немедленного ответа, когда важна своевременная доставка данных. Классический пример — события наведения мышкой.
 


 
# Don't buffer data-sends (disable Nagle algorithm). tcp_nodelay on; 

Стоит обратить внимание на ещё две директивы для keep-alive подключений. Их назначение выглядит очевидным.
 


 
# Timeout for keep-alive connections. Server will close connections after this time. keepalive_timeout 30; # Number of requests a client can make over the keep-alive connection. keepalive_requests 1000; 

Чтобы высвободить дополнительную память, выделенную под сокеты, включите директиву reset_timedout_connection. Она разрешит серверу закрывать подключение тех клиентов, которые перестали отвечать.
 


 
# Allow the server to close the connection after a client stops responding. reset_timedout_connection on; 

Ещё можно существенно уменьшить тайм-ауты для директив client_body_timeout и send_timeout (дефолтное значение обеих — 60 секунд). Первая — ограничивает время на чтение тела запроса от клиента. Вторая — время ответа клиенту. Таким образом, если клиент не начнёт читать данные в указанный промежуток времени, то Nginx закроет подключение.
 


 
# Send the client a "request timed out" if the body is not loaded by this time. client_body_timeout 10; # If the client stops reading data, free up the stale client connection after this much time. send_timeout 2; 

И, конечно же, сжатие данных. Плюс — единственный и очевидный: уменьшение размера пересылаемого трафика. Минус — единственный и очевидный: не работает для MSIE 6 и ниже. Отключить сжатие для этих браузеров можно директивой gzip_disable, указав в качестве значения специальную маску “msie6”, которая соответствует регулярному выражению “MSIE [4-6]\.”, но работает быстрее.
 


 
# Compression. gzip on; gzip_min_length 10240; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; gzip_disable "msie6"; 

Не стоит копировать приведенные настройки один в один. Я советую применять их по одной, каждый раз запуская какую-нибудь утилиту для нагрузочного тестирования (например, Tsung). Это весьма важно для понимания, какие настройки реально ускоряют ваш веб-сервер. Методичность в тестировании сэкономит вам уйму времени.

Статьи

Сделайте заказ с сайта и получите 10% скидку на услугу

Заказ услуги с сайта raybin.ru

Нажимая на кнопку "Получить консультацию", я даю согласие на обработку персональных данных и соглашаюсь c условиями политики конфиденциальности
CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
Заказать бесплатную SEO-консультацию

Запрос бесплатной SEO - консультации с сайта raybin.ru

Нажимая на кнопку "Получить консультацию", я даю согласие на обработку персональных данных и соглашаюсь c условиями политики конфиденциальности
CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
Письмо в компанию Райбин

Письмо в компанию RAYBIN

Нажимая на кнопку "Получить консультацию", я даю согласие на обработку персональных данных и соглашаюсь c условиями политики конфиденциальности
CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.