К бою готов! Руководство по оптимизации Nginx

Большинство руководств по установке и настройке Nginx дают вам основы — apt-get install package, измените несколько строк здесь и там, и у вас готов веб-сервер! В большинстве случаев ванильная установка будет прекрасно работать для обслуживания вашего сайта. Тем не менее, если вы действительно пытаетесь выжать производительность из Nginx, вы должны будете пойти немного дальше. В этом руководстве я объясню какие параметры в Nginx должны быть точно настроены для оптимизации производительности для обслуживания большого количества клиентов. Это не полное руководство по тонкой настройки. Это краткая информация о некоторых настройках для повышения производительности. Ваш прирост в производительности может менять в зависимости от конкретной конфигурации и железа.

Базовая (оптимизированная) конфигурация

Единственный файл, который мы будем изменять nginx.conf, который содержит все свои настройки для Nginx. Надеюсь вы в состоянии найти nginx.conf в /etc/nginx/ на вашем сервере. Во-первых, мы поговорим о некоторых глобальных настройках, а затем пройдемся по каждому модулю в файле и поговорим о том, какие настройки помогут вам найти лучший вариант для обработки большого количества запросов, и почему они увеличивают производительность. Окончательный файл конфигурации можно найти в конце этого поста.

Верхний уровень конфига

Nginx имеет несколько параметров верхнего уровня, которые находятся за пределами модулей в файле nginx.conf.

user и pid оставим по-умолчанию, т.к. они нам не помогут в увеличении производительности.

worker_processes изменяет количество процессов, которое должен использовать Nginx для обслуживания вашего сайта. Оптимальное значение зависит от множества факторов, включая (но не ограничиваясь) число ядер процессора, колличество жестких дисков для хранения данных и характер нагрузки. Если вы сомневаетесь, то установить этот параметр равный количеству доступных ядер процессора и это будет отличным началом (значение «auto» попытается автоматически определить это).

worker_rlimit_nofile устанавливает ограничение на максимальное количество открытых файлов для процессов. Если он не установлен, то ваша ОС сама будет ограничивать это. Скорее всего ваша ОС и Nginx может обрабатывать более «ulimit -n«, поэтому мы установим его настолько великим, чтобы никогда не было проблем с «слишком много открытых файлов» (прим. преводчика: too many open files). Не забудьте обновить это знанчие в своей операционной системе.

Модуль Events

Этот модуль содержит все параметры обработки соединений в Nginx.

worker_connections устанавливает максимальное количество одновременных соединений на одном рабочем процессе. Так как мы столкнулись уже с worker_rlimit_nofile, то можно смело устанавливать его довольно большим.

multi_accept говорит Nginx принимать столько соединений, сколько возможно после получения уведомления о новом соединении.

use устанавливае какой метод обработки мы должны использовать для мультиплексирования клиентов на потоках. Если вы используете Linux 2.6+, то вы должны использовать Epoll. Если вы используете *BSD, то вы должны использовать Kqueue. Кроме того, если вы не включите этот параметр, то Nginx выберит его за вас. Хотите узнать большье о методах обработки соединений? Начните с документации.

Модуль HTTP

Контролирует все основные функции обработки HTTP. Тут есть довольно много настроек и мы будем рассматривать их по частям.

sendfile позволяет использовать sendfile(). Это функци ОС, она копирует данные с диска сразу в кэш ОС и так как копирование происходит в ядре ОС, sendfile() более эффетивен чем read(), а затем write() (подробнее о sendfile()).

tcp_nopush позволяет отправлять все заголовки одним пакетом, а не один за другим.

tcp_nodelay заставляет Nginx не буфиризировать данные и отправлять маленькими, короткими очередями — утанавливайте этот параметр только для приложений, которые часто отправляют небольшие пакеты данных, не получая немедленный ответ, где требуется своевременная доставка данных.

access_log устанавливает, будет ли писаться журнал доступа. Отлючив журнал доступа вы выигрываете в скорости за счет ввода-вывода на диске (IO aka, YOLO).

error_log устанавливает логирование только критических ошибок (флаг crit).

keepalive_timeout назначает таймаут для keep-alive соединения. Сервер будет закрывать соединения по истечению этого времени. Мы становим его малым, так как каждое соединение держит открытым файл.

client_header_timeout и client_body_timeout устанавливает таймаут для заголовка и тела запроса соответственно. Установим их на таком же низком уровне.

reset_timeout_connection закрывает соединения для не отвечающих клиентов. Это позволит высвободить всю память, связанную с клиентом.

send_timeout устанавливает таймаут ответа клиенту. Этот таймаут не применяется ко всей передаче, а только между двумя последовательными операциями чтения. Если клиент не читал никаких данных для в это рвемя, то Nginx разрывает связь.

директива include влючает содержимое другого файла в текущий. Здесь мы используем его для загрузки списка MIME-типов, который будет использован далее.

default_type устанавливает MIME-тип по-умолчанию, который будет включен в наш заголовок.

charset соответственно устанавливает кодировку по-умолчанию.

gzip включает сжатие отсылаемых данных. Это позволит экономить на объеме отправляемых данных.

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

gzip_proxied позволяет или запрещает сжатие ответа на основе запроса/ответа. Мы установим его как any, чтобы сжимать и все запросы.

gzip_min_lenght устанавливает минимальное количество байт необходимое для сжатия. Если запрос занимает менее 256 байт, то мы не будем сжимать его, так как это будет замедлять общий процесс обработки запроса.

gzip_comp_level устанавливает степень сжатия данных. Возможное значение от 1 до 9. 9 самый медленный, но на выходе данные с самым маленьким объемом. Установим 4, чтобы сбалансировать скорость и степерь сжатия.

gzip_types устаналивает какие MIME-типы данных сжимать.

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 снова используется для включения файлов конфигурации в текущий. В том числе и настройки других модулей сервера.

Окончательный файл конфигурации

После редактирования файлов конфигурации, перезапустите nginx для того, чтобы убедиться, что он использует актуальные настройки.

Заключение

Поехали! Теперь ваш Nginx готов к бою с армией посетителей, которые замедляли работу сервера ранее. Это ни в коем случае не является единственным путем, которым вы можете пойти, ускоряя ваш сайт. Я буду писать новые посты, в которых раскажу и другие способы в ближайшее время.

Здавайте вопросы и пишите предложения в комментариях.

Оригинальный пост на английском языке