Настройка и конфигурация Nginx.

Сегодня я хочу поговорить о настройке веб сервера Nginx, установка которого была описана в предыдущей статье.

Функционирование nginx определяется конфигурационным файлом nginx.conf, находящимся в директории /etc/nginx. Nginx состоит из модулей, модули настраиваются директивами, директивы указываются в конфигурационном файле. Директивы могут быть простыми или блочными.

Простая директива состоит из имени и указанного рядом с ним параметра, имя и параметр разделяются между собой пробелом, в конце директивы ставится точка с запятой. Блочная директива устроена так же как и простая, но вместо точки с запятой, после имени и параметра идет набор дополнительных функций, помещенных внутри фигурных скобок {}.

Если в блочной директиве внутри фигурных скобок заданы другие директивы, то она называется контекстом, примерами могут служить: events, http, server, location.

Директивы расположенные вне любого контекста считаются принадлежащими контексту main. Контексты events и http всегда должны находиться внутри контекста main. Контекст server должен находиться внутри контекста http, а location внутри контекста server.

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

Файл nginx.conf создаваемый по умолчанию, можно смело удалять, проще написать свой, чем править существующий.

Удаляем дефолтный файл
rm -f /etc/nginx/nginx.conf

Создаем свой файл
touch /etc/nginx/nginx.conf

Начинаем писать свою конфигурацию.

nano /etc/nginx/nginx.conf

Контекст main

Укажем пользователя от имени которого будет работать сервер. При установке сервера был создан пользователь nginx, он и будет основным пользователем.

# Пользователь
user nginx;

Определим число worker_processes или другими словами, рабочих процессов. Число процессов должно равняться числу процессорных ядер, хотя для последних версий nginx данный параметр рекомендуют устанавливать в значение auto. Поскольку на моем недорогом VPS/VDS сервере доступно одно ядро, то я устанавливаю значение равное единице.

# Количество рабочих процессов
worker_processes 1;

Также зададим приоритет рабочих процессов, это нужно для того, чтобы при сильной нагрузке сервер сразу не упал мог продолжать обрабатывать запросы клиентов. Значения могут варьироваться от -20 до 20, причем чем больше будет отрицательное значение, тем больше будет приоритет процесса.

# Приоритет рабочих процессов
worker_priority -5;

Указываем местонахождение pid-файла и лог-файла ошибок. Отмечаться будут только ошибки критического уровня, другими словами фиксация ошибок практически прекращается, в логах будут только события связанные со стартом или перезагрузкой сервера. Чем меньше производится записей в лог-файлы, тем меньше нагрузка на сервер.

# Pid-файл и error_log файл сервера
pid       /var/run/nginx.pid;
error_log /var/log/nginx/error.log crit;

Контекст events

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

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

ulimit -n

Значение скорее всего будет равно 1024, это значение можно задать для worker_connections.

Директива use задает метод обработки соединений, в Linux следует использовать метод epoll. Включение multi_accept позволяет принимать максимально возможное количество соединений.

events {
    # Максимальное число соединений на один рабочий процесс
    worker_connections 1024;
    
    # Метод обработки соединений
    use                epoll;
    
    # Принимаем максимально возможное количество соединений
    multi_accept       on;
}

Контекст http

Отдельно разберем директиву include подключающую в конфигурацию дополнительные файл или файлы. Рассмотрим несколько примеров чтобы понять как она работает.

Для включения в конфигурацию отдельного файла, например test.conf, нужно указать имя файла и каталог в котором он находится.

include /etc/nginx/sites-enabled/test.conf;

Для включения всех файлов из каталога, должен быть указан каталог и символ "*", теперь все файлы из указанного каталога будут включены в конфигурацию.

include /etc/nginx/sites-enabled/*;

Можно подключить только определенный вид файлов, например имеющих расширение ".conf", для этого нужно указать "*.conf".

include /etc/nginx/sites-enabled/*.conf;

Продолжаем писать конфигурацию и подключаем файл с MIME-типами данных. Данный файл содержит список MIME заголовков и расширений передающихся по сети в соответствии со стандартом MIME. По умолчанию файл mime.types находится в директории /etc/nginx, поэтому в include достаточно просто указать имя файла.

# Задаем расположение файла с MIME типами
include mime.types;

Задаем MIME-тип ответов по умолчанию.

# Задаем тип ответов по умолчанию
default_type application/octet-stream;

Добавим системный вызов sendfile. Системный вызов активирует передачу данных между файловыми дескрипторами посредством ядра, а не при помощи связки read + write. Sendfile позволяет отправлять данные сразу в сеть, минуя процесс их копирования и тем самым повышая производительность.

# Включаем системный вызов
sendfile on;

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

# Ограничиваем объем данных для sendfile
sendfile_max_chunk 128k;

Поскольку sendfile активирована, то в таком случае нужно добавить tcp_nopush, директива позволяет передавать заголовок ответа и начало файла одним пакетом.

# Заголовок ответа и начало файла одним пакетом
tcp_nopush on;

Отключаем буферизацию соединений перешедших в состояние keep-alive.

# Отключаем буферизацию keep-alive соединений
tcp_nodelay on;

Установим временной промежуток в течении которого keep-alive соединение с клиентом не будет закрыто, если пользователь перестал отвечать. Поддерживая неактивное keep-alive соединение, мы тем самым занимаем соединение, которое может использоваться по другому.

# Разрывать неактивное keep-alive соединение через...
keepalive_timeout 10;

Зададим максимальное число запросов для одного keep-alive соединения. После достижения максимального числа запросов соединение будет закрыто.

# Максимальное число запросов для одного keep-alive соединения
keepalive_requests 100;

reset_timedout_connection закрывает подключения для переставших отвечать клиентов.

# Скидываем переставших отвечать
reset_timedout_connection on;

Установим таймаут чтения тела запроса для клиента. Если по истечении установленного времени клиент ничего не ответит, то ему будет возвращена ошибка 408 - Request Time-out.

# Таймаут для чтения тела запроса клиента
client_body_timeout 5;

Установим таймаут чтения заголовка запроса для клиента. Если по истечении установленного времени клиент не передаст заголовок полностью, то ему будет возвращена ошибка 408 - Request Time-out.

# Таймаут для чтения заголовка запроса клиента
client_header_timeout 5;

Установим временной промежуток для передачи ответа клиента. Если по истечении времени клиент не ответит, то соединение будет закрыто.

# Время для ответа
send_timeout 3;

Зададим размер буфера для заголовка запроса от клиента.

# Размер буфера для заголовка запроса от клиента
client_header_buffer_size 2k;

При поступлении от клиентов больших запросов, можно выделять дополнительные буферы с помощью директивы large_client_header_buffers. Строка запроса не должна быть больше размера одного буфера, иначе клиенту будет возвращена ошибка 414 - Request URI Too Large. Поле заголовка запроса также не должно превышать размер одного буфера, иначе клиенту будет возвращена ошибка Bad Request.

Буферы выделяются по мере необходимости. Если по окончанию обработки запроса соединение переходит в состояние keep-alive буферы освобождаются. Может использоваться для защиты от различных ботов или DoS-атак.

# Выделяем дополнительные буферы для больших запросов
large_client_header_buffers 2 2k;

Директивой client_body_buffer_size установим размер буфера для чтения тела запроса клиента.

# Буфер чтения тела запроса клиента
client_body_buffer_size 256k;

client_max_body_size задает размер тела запроса клиента и ограничивает максимальный размер файла, который можно загрузить на сервер посредством PHP.

# Максимальный размер тела запроса от клиента (влияет на размер загружаемого файла)
client_max_body_size 13m;

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

access_log off;

В качестве меры защиты можно отключить вывод версии сервера в заголовках ответов и на страницах ошибок.

server_tokens off;

Укажем каталог в котором будут находиться конфигурационные файлы сайтов.

# Подключение конфигураций сайтов
include /etc/nginx/sites-enabled/*;

Подводя итог статьи, привожу готовый файл nginx.conf.

### nginx.conf ###
### Располагается в /etc/nginx/

    # Пользователь сервера
    user                        nginx;

    # Рабочие процессы & Приоритет процессов 
    worker_processes            1;
    worker_priority             -5;

    # Лог-файл ошибок & Pid-файл
    error_log                   /var/log/nginx/error.log crit;
    pid                         /var/run/nginx.pid;
 
events {
    # Максимально возможное кол-во соединений
    # Прием максимально возможного кол-ва соединений
    # Метод обработки соединений
    worker_connections          1024;
    multi_accept                on;
    use                         epoll;
}
 
http {

    include                     mime.types;
    default_type                application/octet-stream;

    # Активация системного вызова sendfile 
    # Ограничение объема данных за один вызов
    # Заголовок ответа и начало файла одним пакетом
    
    sendfile                    on;
    sendfile_max_chunk          128k;
    tcp_nopush                  on;

    # Буферизация keep-alive соединений
    # Таймаут в течении которого поддерживается keep-alive соединение
    # Максимальное число запросов keep-alive соединения
    
    tcp_nodelay                 on;
    keepalive_timeout           10;
    keepalive_requests          100;

    # Закрывать соединения для переставших отвечать клиентов
    # Таймаут для чтения тела запроса от клиента
    # Таймаут для чтения заголовка запроса от клиента
    
    reset_timedout_connection   on;
    client_body_timeout         5;
    client_header_timeout       5;

    # Размер буфера для заголовка запроса от клиента
    # Дополнительные буферы для больших запросов
    # Размер буфера для чтения тела запроса от клиента
    # Максимальный размер запроса клиента
    # Таймаут передачи ответа для клиента
    
    client_header_buffer_size   2k;
    large_client_header_buffers 2 2k;
    client_body_buffer_size     256k;
    client_max_body_size        13m;
    send_timeout                3;

    # Отключение логов доступа
    # Отключение версии сервера
    
    access_log                  off;
    server_tokens               off;
 
    # Подключение сайтов 
    include                     /etc/nginx/sites-enabled/*;

}

О конфигурационных файлах сайтов мы поговорим в следующей статье, в которой будет рассмотрена дальнейшая настройка Nginx для WordPress-сайта.

Ответить:

Please enter your comment!
Please enter your name here