Содержание

Оптимизация NGINX

Ускоряем сайт, сокращая время ответа сервера

516 982 слов 5 минут

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

Не забывайте, что после внесения изменений необходимо проверять их корректность командой:

nginx -t

А чтобы применить настройки, необходимо перезапустить nginx:

nginx -s reload

Один из самых эффективных методов ускорить ответ от вашего веб-сервера nginx - это включить GZIP сжатие.

http {
  ...
  
    gzip                on;
    gzip_min_length     1000;
    gzip_proxied        expired no-cache no-store private auth;
    gzip_types          text/plain text/css text/javascript application/javascript application/x-javascript text/xml application/xml application/xml+rss application/json;
    gzip_disable        "msie6";
    
  ...
}

gzip включает сжатие.

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

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

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

gzip_disable запрещает для перечисленных параметров заголовка User-Agent сжатие. В данном примере для Internet Explorer 6 сжатие применяться не будет, так как данный браузер не умеет принимать сжатые ответы.

Еще один способ увеличить скорость ответа - это включить кэширвоание на стороне клиента.


server {
  ...
  
    # Media
    location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|mp4|ogg|ogv|webm|htc)$ {
        expires 30d;
    }

    # CSS and Js
    location ~* \.(css|js|woff2)$ {
        expires 365d;
    }

  ...
}

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

worker_processes  auto;
worker_priority     -2;
...
events {
    worker_connections  2048;
    multi_accept on;
}
...
http {
    ...
    keepalive_timeout          45;
    reset_timedout_connection  on;
    client_body_timeout        35;
    send_timeout               30;
    ...
}

worker_processes - Определяет количество рабочих процессов. Обычно, выставляют равному числу ядер, но в новых версиях его лучше устанавливать в auto. По умолчанию 1

worker_connections - Устанавливает максимальное количество соединений одного рабочего процесса, то есть nginx будет обрабатывать worker_processes * worker_connections, остальные запросы ставить в очередь. Следует выбирать значения от 1024 до 4096. По умолчанию 512.

multi_accept - Позволяет принимать максимально возможное количество соединений. Иначе, процесс nginx за один раз будет принимать только одно новое соединение. По умолчанию off.

keepalive_timeout - Отвечает за максимальное время поддержания keepalive-соединения, в случае, если пользователь по нему ничего не запрашивает. Для современных систем, стоит выставить от 30 до 50. В нашем случае 45. По умолчанию 75.

reset_timedout_connection - Если клиент перестал читать страницу, Nginx будет сбрасывать соединение с ним. По умолчанию off.

client_body_timeout - Ждет выставленное количество секунд тело запроса от клиента, после чего сбрасывает соединение. По умолчанию 60.

send_timeout - Если клиент прекратит чтение ответа, Nginx подождет выставленное количество секунд и сбросит соединение. По умолчанию 60.

http {
  ...
    sendfile      on;
    aio           on;
    tcp_nopush    on;

    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 45s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    ...
}

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

aio включает использование асинхронного обращения к файлам, что избавит от очередей запросов.

tcp_nopush позволит передавать заголовок ответа и начало файла в одном пакете.

open_file_cache по умолчанию выключена. Задает настройку для кэширования информации о файлах, с которыми работает nginx. По умолчанию выключено.

open_file_cache_valid задает время, через которое веб-сервер будет проверять актуальность данных. По умолчанию 60 секунд.

open_file_cache_min_uses задает минимальное число обращений к файлу, чтобы дескриптор файла оставался открытым в кэше.

open_file_cache_errors включает или выключает кэширование ошибок.

Помимо уменьшения времени отклика веб-сервера, необходимо позаботиться о безопасности. Разберем основные http заголовки, которые могут представлять угрозу.

Заголовок X-XSS-Protection может предотвратить некоторые XSS-атаки.

Вы можете реализовать защиту XSS, используя три варианта в зависимости от конкретной потребности.

  • X-XSS-Protection: 0; Это полностью отключит фильтр
  • X-XSS-Protection: 1; Это включает фильтр, но очищает только потенциально вредоносные скрипты
  • X-XSS-Protection: 1; mode = block; Это включает фильтр и полностью блокирует страницу.
server {
  ...

  add_header X-XSS-Protection "1; mode=block";
    
  ...
}

Заголовок X-Frame-Options позволяет снизить уязвимость вашего сайта для clickjacking-атак. Этот заголовок служит инструкцией для браузера не загружать вашу страницу в frame/iframe. Не все браузеры поддерживают этот вариант.

Настроить X-Frame-Options можно тремя способами:

  • DENY: это полностью отключит функции iframe.
  • SAMEORIGIN: iframe может использоваться только кем-то из того же источника.
  • ALLOW-FROM: Это позволит размещать страницы в окнах iframe только с определенных URL-адресов.
server {
  ...

  add_header X-Frame-Options "DENY";
    
  ...
}

Аналогично механизму браузеров блокировки стороннего контента Adobe Flash имеет свой. Он регулируется файлами crossdomain.xml сайта, начиная с корневого каталога. Проблема с механизмом в том, что на любом уровне вложенности корневой регулирующий файл (политика безопасности) может быть переопределен. Чтобы избежать таких ситуаций, необходимо задать этот HTTP-заголовок.

Доступно несколько вариантов настройки:

  • none - никакая политика не допускается
  • master-only - разрешить только главную политику
  • all - все позволено
  • by-content-only - Разрешить только определенный тип контента. Пример - XML
  • by-ftp-only - применимо только для FTP-сервера
server {
  ...

  add_header X-Permitted-Cross-Domain-Policies master-only;
    
  ...
}

Заголовок Strict-Transport-Security запрещает использование незащищенного HTTP соединения на сайте, если есть защищенное HTTPS.

server {
  ...

  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
  ...
}

Рейтинг наиболее опасных к использованию возможностей браузера возглавляет возможность Internet Explorer «угадывать» тип файла, игнорируя его MIME-тип.

При передаче от сервера к браузеру все файлы имеют тот или иной тип, который прямо указывает на суть содержимого файла. Однако, Internet Explorer имеет встроенный механизм, который позволяет по-содержимому файла переопределить его тип.

Таким образом, обычные текстовые файлы могут быть интерпретированы как JavaScript со всеми вытекающими последствиями. Например, если у вас на сайте запрещена загрузка текстовых файлов с расширениями .js пользователями, то они могут загрузить в виде картинок текстовый файл, содержащий JavaScript-код, который может быть исполнен браузером.

server {
  ...

  add_header X-Content-Type-Options nosniff;
    
  ...
}

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

Комментарии

Struchkov Mark
Struchkov Mark
Знаете еще способы оптимизации NGINX? Напишите в комментариях