Большинство руководств по установке и настройке Nginx дают вам основы — apt-get install package, измените несколько строк здесь и там, и у вас готов веб-сервер! В большинстве случаев ванильная установка будет прекрасно работать для обслуживания вашего сайта. Тем не менее, если вы действительно пытаетесь выжать производительность из Nginx, вы должны будете пойти немного дальше. В этом руководстве я объясню какие параметры в Nginx должны быть точно настроены для оптимизации производительности для обслуживания большого количества клиентов. Это не полное руководство по тонкой настройки. Это краткая информация о некоторых настройках для повышения производительности. Ваш прирост в производительности может менять в зависимости от конкретной конфигурации и железа.
Базовая (оптимизированная) конфигурация
Единственный файл, который мы будем изменять nginx.conf, который содержит все свои настройки для Nginx. Надеюсь вы в состоянии найти nginx.conf в /etc/nginx/ на вашем сервере. Во-первых, мы поговорим о некоторых глобальных настройках, а затем пройдемся по каждому модулю в файле и поговорим о том, какие настройки помогут вам найти лучший вариант для обработки большого количества запросов, и почему они увеличивают производительность. Окончательный файл конфигурации можно найти в конце этого поста.
Верхний уровень конфига
Nginx имеет несколько параметров верхнего уровня, которые находятся за пределами модулей в файле nginx.conf.
1 2 3 4 5 6 |
user www-data; pid /var/run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65000; |
user и pid оставим по-умолчанию, т.к. они нам не помогут в увеличении производительности.
worker_processes изменяет количество процессов, которое должен использовать Nginx для обслуживания вашего сайта. Оптимальное значение зависит от множества факторов, включая (но не ограничиваясь) число ядер процессора, колличество жестких дисков для хранения данных и характер нагрузки. Если вы сомневаетесь, то установить этот параметр равный количеству доступных ядер процессора и это будет отличным началом (значение «auto» попытается автоматически определить это).
worker_rlimit_nofile устанавливает ограничение на максимальное количество открытых файлов для процессов. Если он не установлен, то ваша ОС сама будет ограничивать это. Скорее всего ваша ОС и Nginx может обрабатывать более «ulimit -n«, поэтому мы установим его настолько великим, чтобы никогда не было проблем с «слишком много открытых файлов» (прим. преводчика: too many open files). Не забудьте обновить это знанчие в своей операционной системе.
Модуль Events
Этот модуль содержит все параметры обработки соединений в Nginx.
1 2 3 4 5 6 7 |
events { worker_connections 2048; multi_accept on; use epoll; } |
worker_connections устанавливает максимальное количество одновременных соединений на одном рабочем процессе. Так как мы столкнулись уже с worker_rlimit_nofile, то можно смело устанавливать его довольно большим.
multi_accept говорит Nginx принимать столько соединений, сколько возможно после получения уведомления о новом соединении.
use устанавливае какой метод обработки мы должны использовать для мультиплексирования клиентов на потоках. Если вы используете Linux 2.6+, то вы должны использовать Epoll. Если вы используете *BSD, то вы должны использовать Kqueue. Кроме того, если вы не включите этот параметр, то Nginx выберит его за вас. Хотите узнать большье о методах обработки соединений? Начните с документации.
Модуль HTTP
Контролирует все основные функции обработки HTTP. Тут есть довольно много настроек и мы будем рассматривать их по частям.
1 2 3 4 5 6 7 8 9 |
http { sendfile on; tcp_nopush on; tcp_nodelay on; ... } |
sendfile позволяет использовать sendfile(). Это функци ОС, она копирует данные с диска сразу в кэш ОС и так как копирование происходит в ядре ОС, sendfile() более эффетивен чем read(), а затем write() (подробнее о sendfile()).
tcp_nopush позволяет отправлять все заголовки одним пакетом, а не один за другим.
tcp_nodelay заставляет Nginx не буфиризировать данные и отправлять маленькими, короткими очередями — утанавливайте этот параметр только для приложений, которые часто отправляют небольшие пакеты данных, не получая немедленный ответ, где требуется своевременная доставка данных.
1 2 3 |
access_log off; error_log /var/log/nginx/error.log crit; |
access_log устанавливает, будет ли писаться журнал доступа. Отлючив журнал доступа вы выигрываете в скорости за счет ввода-вывода на диске (IO aka, YOLO).
error_log устанавливает логирование только критических ошибок (флаг crit).
1 2 3 4 5 6 7 8 |
keepalive_timeout 20; client_header_timeout 20; client_body_timeout 20; reset_timedout_connection on; send_timeout 20; |
keepalive_timeout назначает таймаут для keep-alive соединения. Сервер будет закрывать соединения по истечению этого времени. Мы становим его малым, так как каждое соединение держит открытым файл.
client_header_timeout и client_body_timeout устанавливает таймаут для заголовка и тела запроса соответственно. Установим их на таком же низком уровне.
reset_timeout_connection закрывает соединения для не отвечающих клиентов. Это позволит высвободить всю память, связанную с клиентом.
send_timeout устанавливает таймаут ответа клиенту. Этот таймаут не применяется ко всей передаче, а только между двумя последовательными операциями чтения. Если клиент не читал никаких данных для в это рвемя, то Nginx разрывает связь.
1 2 3 4 5 |
include /etc/nginx/mime.types; default_type text/html; charset UTF-8; |
директива include влючает содержимое другого файла в текущий. Здесь мы используем его для загрузки списка MIME-типов, который будет использован далее.
default_type устанавливает MIME-тип по-умолчанию, который будет включен в наш заголовок.
charset соответственно устанавливает кодировку по-умолчанию.
1 2 3 4 5 6 7 8 9 10 11 |
gzip on; # gzip_static on; gzip_proxied any; gzip_min_length 256; gzip_comp_level 4; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; |
gzip включает сжатие отсылаемых данных. Это позволит экономить на объеме отправляемых данных.
gzip_static включает поиск предварительно сжатых файлов. Этот парамет (в нашем примере закомметирован) требует предварительного сжатия ваших файлов, но не позволяет использовать максимально возможную степень сжатия (подробнее о gzip_static).
gzip_proxied позволяет или запрещает сжатие ответа на основе запроса/ответа. Мы установим его как any, чтобы сжимать и все запросы.
gzip_min_lenght устанавливает минимальное количество байт необходимое для сжатия. Если запрос занимает менее 256 байт, то мы не будем сжимать его, так как это будет замедлять общий процесс обработки запроса.
gzip_comp_level устанавливает степень сжатия данных. Возможное значение от 1 до 9. 9 самый медленный, но на выходе данные с самым маленьким объемом. Установим 4, чтобы сбалансировать скорость и степерь сжатия.
gzip_types устаналивает какие MIME-типы данных сжимать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# cache informations about file descriptors, frequently accessed files # can boost performance, but you need to test those values open_file_cache max=65000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; ## # Virtual Host Configs # aka our settings for specific servers ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } |
open_file_cache устанавливает максимальное количество записей в кэше, а также время кэширования. Установим наш максимум относительно высоким и избавимся от кэша через 20 сек.
open_file_cache_valid определяет интервал, когда необходимо проверять актуальность информацию о элементе в open_file_cache.
open_file_cache_min_uses определяет минимальное число обращений к файлу в течение времени, указанного в директиве inactive параметра open_file_cache.
open_file_cache_errors определяет, будет ли кэшироваться ошибки при поиске файлов.
include снова используется для включения файлов конфигурации в текущий. В том числе и настройки других модулей сервера.
Окончательный файл конфигурации
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
user www-data; pid /var/run/nginx.pid; worker_processes auto; worker_rlimit_nofile 65000; events { worker_connections 2048; multi_accept on; use epoll; } http { sendfile on; tcp_nopush on; tcp_nodelay on; access_log off; error_log /var/log/nginx/error.log crit; keepalive_timeout 20; client_header_timeout 20; client_body_timeout 20; reset_timedout_connection on; send_timeout 20; include /etc/nginx/mime.types; default_type text/html; charset UTF-8; gzip on; # gzip_static on; gzip_proxied any; gzip_min_length 256; gzip_comp_level 4; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; open_file_cache max=65000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } |
После редактирования файлов конфигурации, перезапустите nginx для того, чтобы убедиться, что он использует актуальные настройки.
1 |
sudo service nginx reload |
Заключение
Поехали! Теперь ваш Nginx готов к бою с армией посетителей, которые замедляли работу сервера ранее. Это ни в коем случае не является единственным путем, которым вы можете пойти, ускоряя ваш сайт. Я буду писать новые посты, в которых раскажу и другие способы в ближайшее время.
Здавайте вопросы и пишите предложения в комментариях.