Оптимизация сервера с помощью Nginx и pm-static

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

Продолжим оптимизацию разработанного приложения. Мы начали с создания эскизов картинок «налету», которое занимает 28 секунд.

Оптимизация сервера при помощи Nginx и pm-static

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


Оптимизация сервера при помощи Nginx и pm-static

Устранение проблем

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

При развертывании Homestead Improved блок на Windows может появиться проблема общих папок. Ее можно решить добавлением параметры type: «nfs» к папке folder в Homestead.yaml.

Оптимизация сервера при помощи Nginx и pm-static

Также необходимо запустить vagrant up из интерфейса shell/powershell с правами администратора.

До этого требовалось от 20 до 30 секунд на загрузку при каждом запросе. И нам не удавалось увеличить скорость выше одного запроса в секунду.

Оптимизация сервера при помощи Nginx и pm-static

Процесс тестирования

Мы установили Locust на наш хост и создали простой скрипт locustfile.py:

from locust import HttpLocust, TaskSet, taskclass UserBehavior(TaskSet): @task(1) def index(self): self.client.get("/")class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 300 max_wait = 1000

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

После этого мы запустили Locust и подключили к приложению 100 посетителей:

Оптимизация сервера при помощи Nginx и pm-static

На стороне сервера мы использовали PHP 7.1.10, Nginx 1.13.3 и MySQL 5.7.19, на Ubuntu 16.04.

PHP-FPM и параметр диспетчера процессов

php-fpm создает собственные процессы. Управление ими настраивается в /etc/php/7.1/fpm/pool.d/www.conf. В данном файле находятся параметра менеджера процессов. Этот настройка поддерживает следующие значения: dynamic, ondemand и static. Лучше использовать значение dynamic, поскольку оно может серверу определить число дочерних процессов на основе заданных лимитов в конфигурационном файле.

pm = dynamic; The number of child processes to be created when pm is set to 'static' and the; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.; This value sets the limit on the number of simultaneous requests that will be; served.pm.max_children = 6; The number of child processes created on startup.; Note: Used only when pm is set to 'dynamic'; Default Value: min_spare_servers +(max_spare_servers - min_spare_servers) / 2pm.start_servers = 3; The desired minimum number of idle server processes; Note: Used only when pm is set to 'dynamic'; Note: Mandatory when pm is set to 'dynamic'pm.min_spare_servers = 2; The desired maximum number of idle server proceses; Note: Used only when pm is set to 'dynamic'; Note: Mandatory when pm is set to 'dynamic'pm.max_spare_servers = 4

Создание процессов происходит по запросу. Но их число ограничено данными минимальными и максимальными значениями.

После исправления проблемы с общими папками в Windows и тестирования при помощи Locust мы смогли приобрести скорость примерно пять запросов за 5 секунду. При этом уровень ошибок составлял 17-19% ошибок при 100 параллельных пользовательских сеансах. Но при увеличении числа запросов, на обработку каждого из них серверу требовалось более 10 секунд.

Далее мы поменяли установки pm setting на ondemand. Но это ещё больше увеличило время начального ожидания и число сбоев. В результате приложение могло обрабатывать от четырех до шести запросов в секунду. Время ожидания и частота отказов были аналогичны параметру dynamic.

Далее мы попробовали использовать настройка pm = static, позволяющий PHP процессу использовать максимум ресурсов сервера. Данный настройка означает, что мы постоянно выжимаем максимум из используемой системы.

В результате скорость работы приложения увеличилась на 20%. Хотя число неудачных запросов все ещё было значительным, а время отклика неудовлетворительным. Система была ещё не готова к эксплуатации.

Оптимизация сервера при помощи Nginx и pm-static

Но в Pingdom Tools мы получили приемлемые 3,38 секунды, если система не находилась под нагрузкой:

Оптимизация сервера при помощи Nginx и pm-static

Это означало, что pm static улучшило производительность. Но только при умеренной загрузке.

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

Кэширование Nginx и fastcgi

proxy_cache_path /home/vagrant/Code/ng-cache levels=1:2 keys_zone=ng_cache:10m max_size=10g inactive=60m;proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;fastcgi_cache_path /home/vagrant/Code/ngd-cache levels=1:2 keys_zone=ngd_cache:10m inactive=60m;fastcgi_cache_key "$scheme$request_method$host$request_uri";fastcgi_cache_use_stale error timeout invalid_header http_500;fastcgi_ignore_headers Cache-Control Expires Set-Cookie;add_header NGINX_FASTCGI_CACHE $upstream_cache_status;server { listen 80; listen 443 ssl http2; server_name nginx-performance.app;    root "/home/vagrant/Code/project-nginx/public";    index index.html index.htm index.php;    charset utf-8;    proxy_cache ng_cache;    location / {        try_files $uri $uri/ /index.php?$query_string;    }    location = /favicon.ico { access_log off; log_not_found off; }    location = /robots.txt  { access_log off; log_not_found off; }    access_log off;    error_log  /var/log/nginx/nginx-performance.app-error.log error;    sendfile off;    client_max_body_size 100m;    location ~.php$ {        fastcgi_split_path_info ^(.+.php)(/.+)$;        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;        fastcgi_index index.php;        include fastcgi_params;        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;        fastcgi_intercept_errors off;        fastcgi_buffer_size 16k;        fastcgi_buffers 4 16k;        fastcgi_connect_timeout 300;        fastcgi_send_timeout 300;        fastcgi_read_timeout 300;      fastcgi_cache ngd_cache;      fastcgi_cache_valid 60m;    }    location ~ /.ht {        deny all;    }    ssl_certificate     /etc/nginx/ssl/nginx-performance.app.crt;    ssl_certificate_key /etc/nginx/ssl/nginx-performance.app.key;}

Мы открыли файл виртуального хоста Nginx и добавили приведенные выше параметра. Давайте поясним их.

proxy_cache_path /home/vagrant/Code/ng-cache levels=1:2 keys_zone=ng_cache:10m max_size=10g inactive=60m;

Как объяснялось в статье производительность Apache и Nginx: способы оптимизации, proxy_cache_path используется для кеширования статических ресурсов. Таких как картинки, таблицы стилей, файлы JavaScript. Сам путь должен существовать, так что надо создать данные директории.

levels означает глубину директорий внутри этого пути/папки.

Keys zone –  это имя. Каждый виртуальный хост должен использовать отдельное имя. max_size означает максимальный размер кэша, а inactive — что элементы времени будут храниться в кэше, даже если они не запрашиваются.

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

fastcgi_cache_purge

Это определяет запросы, которые смогут очистить кэш. Nginx(его модуль ngx_http_fastcgi_module) предлагает полный комплект инструментов для кэширования. Пример использования указанной выше директивы:

fastcgi_cache_path /data/nginx/cache keys_zone=cache_zone:10m;map $request_method $purge_method {    PURGE 1;    default 0;}server {...    location / {        fastcgi_pass backend;        fastcgi_cache cache_zone;        fastcgi_cache_key   $uri;        fastcgi_cache_purge $purge_method;    }}

В этом случае запрос PURGE REST сможет удалить данные из кэша.

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

add_header NGINX_FASTCGI_CACHE $upstream_cache_status;

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

Оптимизация сервера при помощи Nginx и pm-static

Способ fastcgi_cache_methods полезен для кеширования конкретных способов запроса, таких как POST. GET и HEAD.

Активировав приведенную выше конфигурацию, как для статического, так и для динамического контента, мы запустили Locust. Мы подключили к системе 100 параллельных посетителей. Разница в результатах была поразительной. Того напряжения, в котором раньше находился сервер, не ощущалось.

Оптимизация сервера при помощи Nginx и pm-static

Кэширование Nginx принесло пару значительных улучшений.

Оптимизация сервера при помощи Nginx и pm-static

При этом процент неудачных запросов снизился с 17% до 0,53%. Далее мы перешли на страницу теста Pingdom и проверили наш веб-сайт:

Оптимизация сервера при помощи Nginx и pm-static

Мы видим, что нам удалось сократить время загрузки страницы. Сейчас оно составляет меньше секунды!

Мы также протестировали одну страницу галереи, у которой есть дополнительный «багаж» похожих и новых галерей.

Оптимизация сервера при помощи Nginx и pm-static

Отчет в файле HAR по данному тесту.

Заключение

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *