12 декабря 2018
- С одной стороны, Wordpress популярен среди вебмастеров благодаря низкому порогу вхождения и универсальности.
- С другой стороны, Wordpress известен медленной скоростью работы.
- Даже статические по сути страницы при каждом обращении к ним проходят через громоздкую систему генерации с выполнением большого количества PHP-кода и SQL-запросов.
- При этом ускорение сайта с помощью кэширования в HTTP-акселераторе (например, Squid в режиме реверсивного прокси или Nginx) использовать нельзя:
- страницы необходимо удалять из кэша, когда они меняются в Вордпрессе;
- но Вордпресс не имеет стандартного способа сообщить HTTP-акселератору о таком изменении.
- Поэтому для Вордпресса создано большое количество кэширующих плагинов — как взаимодействующих с HTTP-акселератором, так и реализующих всю логику внутри самого Вордпресса.
- Главный недостаток плагинов второго типа — хотя количество выполняемого PHP-кода кардинально сокращается, сам факт его выполнения уже приводит к низкой производительности.
- Cachify является плагином первого типа — за счёт взаимодействия с Nginx кэшированные страницы отдаются вообще без передачи запроса в PHP/WP/MySQL.
- Благодаря этому производительность сайта на Вордпрессе на большинстве запросов удаётся поднять до производительности статического сайта.
Способ работы:
- Wordpress сохраняет в Memcached всё содержимое, отдаваемое неавторизованным посетителям.
- Nginx обращается к Wordpress'у только в том случае, если результат запроса не найден в Memcached.
Установка пакетов в Debian/Ubuntu:
- Подразумевается, что уже используется связка Nginx + PHP-FPM
- Cachify совместим только с акселератором APC — Xcache и прочие аналоги не поддерживаются.
- Можно использовать nginx-full или nginx-extras, но не nginx-light, т.к. он собран без поддержки memcached
- Итого:
apt-get -y install php-apcu php-memcached memcached nginx-full
Настройка Nginx для кэширования в Memcached:
- Стандартная директива
try_files $uri $uri/ /index.php?$args;
переносится в отдельныйlocation @nocache
- На бывшее место
try_files
помещается запрос страницы из memcached, предваряемый длинным блоком исключений. Не кэшируются и перенаправляются в@nocache
по коду 405 следующие запросы: - с параметрами;
- с типом POST;
- от авторизованных пользователей;
- в админку.
- Если страница не будет обнаружена в memcached, запрос также будет перенаправлен в
@nocache
— по коду 404. - Полный текст настроек см. в https://github.com/pluginkollektiv/cachify/blob/develop/inc/setup/cachify.memcached.nginx.php
Проверка работы:
- Посещаем несколько страниц сайта...
- ..и смотрим, сохранились ли они в кэше:
echo stats items | netcat 127.0.0.1 11211
echo stats cachedump 29 100 | netcat 127.0.0.1 11211
Альтернативный вариант — настройка Nginx для кэширования в APC:
- Данный способ нами пока не протестирован, но его настройка выглядит намного проще — достаточно к каждой директиве fastcgi_pass, передающей запросы из Nginx в PHP-FPM, добавить строку с установкой переменной:
fastcgi_param PHP_VALUE auto_prepend_file=;
Ограничения:
- Cachify предлагает добавлять в настройки Nginx строку «add_header X-Powered-By Cachify», но этого НЕ следует делать в том случае, если add_header уже используются на верхних уровнях, т.к. документация Nginx гласит: «Директивы наследуются с предыдущего уровня при условии, что на данном уровне не описаны свои директивы add_header.»
- Сайт обязан работать либо только через http, либо только через https, т.к. страницы содержат абсолютные ссылки, но сохраняются в memcached без учёта протокола. С другой стороны, в https://github.com/pluginkollektiv/cachify/pull/22 пишут, что сейчас данная проблема уже решена. Тем не менее, принудительный редирект клиентов с HTTP на HTTPS можно выполнить в Nginx'e примерно так:
location / {
if ($http_x_forwarded_proto != "https") { # ..behind standard proxy?
#if ($http_cf_visitor ~ '{"scheme":"http"}') { # ..behind Cloudflare?
return 301 https://$server_name$request_uri; # ..force redirect from HTTP to HTTPS
}
systemctl restart memcached