Попробуем увеличить производительность сайта на WP, без всяких плагинов, регистрации и смс.
Дано нам следующее — крайне «производительный» vps сервер на centos 7, да будем считать, что мы староверы, с 2 ядрами CPU и 4 гигами RAM на борту.
Делаем первоначальный тест wrk.
5 RPS и достаточно большой latency выглядит максимально не очень. Конечно сильный latency еще связан с тем, что я запускаю тест wrk в одной стране а ВМ находится в другой, а также широтой канала, он где-то 40Мбит у этого хостера, но все же, хотелось бы видеть более высокие показатели пусть и у сайта на WP.
Теперь протестируем производительность с помощью google PageSpeed Insigths.
Мобильная версия сайта:
Версия для десктопа:
В целом результат лучше чем ожидалось, но «Performance» проседает.
Что ж давайте исправлять.
Изначально мы ехали на максимально дефолтных конфигах nginx + php-fpm.
Тюнинг nginx
В nginx.conf дописываем следующее
worker_processes 2;
У нас два ядра, именно столько воркеров и выставим.
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
Основное тут использование epoll — это говорит nginx использовать механизм epoll для обработки событий ввода-вывода в Linux. Это позволит nginx более эффективно обрабатывать множество одновременных подключений.
sendfile on;
tcp_nopush on;
tcp_nodelay on;
senfile — эта директива говорит использовать системный вызов sendfile() для передачи файлов через сетевое соединение. Вместо того чтобы прочитывать файл в память и затем отправлять его через сокет, sendfile()
позволяет ядру ОС копировать данные непосредственно из файла в сокет, минимизируя операции ввода-вывода и ускоряя передачу файлов. Это полезно например для статических файлов, таких как изображения, видео и другие ресурсы, которые сервер может отдавать клиентам.
tcp_nopush — эта директива включает опцию «TCP_NOPUSH» для сокетов, что позволяет серверу отправлять заголовки HTTP ответа вместе с частью данных (например, HTML страница) без ожидания полной загрузки всех данных. Это может помочь уменьшить задержку при передаче данных и улучшить производительность.
tcp_nodelay — эта директива включает опцию «TCP_NODELAY» для сокетов, что отключает алгоритм накопления данных перед отправкой. Когда опция включена, данные отправляются как можно быстрее.
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
Тут мы включаем кеширование, что также позволит нам ускорить отдачу контента.
gzip on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
gzip_disable "msie6";
Не забываем включить сжатие gzip.
С основным конфигом nginx закончили, теперь идем в конфиг нашего сайта и добавляем следующий локейшен.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
expires max;
log_not_found off;
access_log off;
}
Здесь мы включаем кеш по максимуму для статики.
Тюним php:
В наш пул коннектов добавляем следующее
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 1000
Используем динамический тип пула. Это значит, что при нагрузки php-fpm сам создаст дополнительное кол-во воркеров, а после снижения нагрузки удалит. Это полезно в нашем случае, тк нам нет смысла держать в памяти статическое кол-во воркеров, занимая ресурсы.
pm.max_children — максимальное кол-во воркеров, которое будет создано. Тут следует учесть, что у php есть параметр memory_limits у нас он дефолтный и равен 128МБ, следовательно при максимальных нагрузках 20 воркеров может скушать каждый по 128МБ, это примерно 2.5Гб памяти. На нашем сервере 4Гига, и примерно 1Гб всегда свободен, те ООМ киллер наступить не должен.
pm.start_servers — начальное кол-во воркеров в пуле. Именно с этим кол-во запустится php-fpm пока не придет нагрузка.
pm.min_spare_servers — минимальное количество «запасных» рабочих процессов в пуле. Если количество свободных (не занятых обработкой запросов) процессов опускается ниже этого значения, PHP-FPM будет создавать дополнительные процессы до достижения минимального порога.
pm.max_spare_servers — максимальное количество «запасных» рабочих процессов в пуле. Когда количество свободных процессов превышает это значение, лишние процессы будут постепенно убиваться, чтобы уменьшить нагрузку на сервер.
Теперь поставим пакет opcache для php и настроим следующий конфиг
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=130987
opcache.max_wasted_percentage=5
opcache.use_cwd=1
opcache.validate_timestamps=1
opcache.revalidate_path=1
opcache.enable_file_override=1
opcache.fast_shutdown=1
opcache.save_comments=1
opcache.load_comments=1
opcache.jit_buffer_size=128M
opcache — это расширение для PHP, предназначенное для кэширования и оптимизации промежуточного байт-кода PHP. PHP-код сначала компилируется в промежуточный байт-код, который интерпретируется движком PHP во время выполнения. OPcache сохраняет этот байт-код в памяти, что позволяет избежать повторной компиляции и ускоряет загрузку и выполнение PHP-скриптов.
jit — это концепция оптимизации выполнения кода, при которой код компилируется в машинный код во время выполнения программы, а не до этого.
Пройдемся по основным параметрам:
opcache.memory_consumption — определяет объем памяти (в мегабайтах), выделенный для хранения кэша байт-кода.
opcache.interned_strings_buffer — устанавливает размер буфера для кэширования интернированных строк, что может улучшить производительность.
opcache.max_accelerated_files — определяет максимальное количество файлов, которые могут быть закэшированы.
opcache.max_wasted_percentage — устанавливает максимальный процент «потерянного» кэша. Если потерянный кэш превысит этот процент, произойдет очистка кэша.
opcache.use_cwd — включает или выключает использование текущей рабочей директории в ключах кэша.
opcache.validate_timestamps — включает или выключает проверку временных меток файлов для определения необходимости перекомпиляции.
opcache.revalidate_path — включает или выключает проверку пути при каждой загрузке файла.
opcache.enable_file_override — позволяет или запрещает использование опции opcache.file_cache_only
, чтобы переопределить кэш файлов.
opcache.fast_shutdown — включает или выключает быстрое завершение работы OPcache при завершении запроса.
opcache.save_comments — включает или выключает сохранение комментариев в байт-коде.
opcache.load_comments — включает или выключает загрузку комментариев из кэша байт-кода.
opcache.jit_buffer_size — этот параметр устанавливает размер буфера для JIT компиляции, если JIT поддерживается.
Перезапускаем nginx + php-fpm и делаем замеры еще раз.
Тест wrk после тюнинга:
Видим прирост в РПС почти в 5 раз. Также latency стал лучше.
Тест PageSpeed после тюнинга:
Перфоманс вырос на 8 пунктов для мобильной версии.
И на 18 пунктов для десктопа.
Это очень неплохой результат для PageSpeed, версия для ПК в зеленой зоне.