Чат Telegram
Группа ВКонтакте
Ускорение блога на WordPress с помощью Varnish

Ускорение блога на WordPress с помощью Varnish

Данная статья является кусочком этой статьи и рассказывает о том, как быстро и просто (не так просто, как установить плагин WP Super Cache, конечно) ускорить сайт на WordPress с помощью Varnish, без лишней воды.

Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно

Скажу сразу, чтобы не было комментариев вроде "Бгг, чтобы вордпресс хоть как-то разогнался пришлось ставить кеширующий сервер": данная статья описывает пример настройки этого замечательного средства для кеширования на примере популярного и на самом деле довольно приемлемого движка.

Опираясь на данный пример можно настроить кеширование любого веб-приложения. Так-то. Поехали.

Было — стало:

Устанавливаем Varnish:

apt-get install varnish

Меняем конфигурацию в файле /etc/varnish/default.vcl

# Сообщаем компилятору о том, что используется новая версия VCL 4
vcl 4.0;

# Настройки бэкенда
backend default {
    .host = "127.0.0.1";
    .port = "81";
}

# Диапазон IP/Хостов, которым разрешено выполнять PURGE-запросы для очистки кэша
acl purge {
    "localhost";
    "127.0.0.1";
}

# Получение запроса от клиента
sub vcl_recv {
    # Разрешить очистку кэша вышеописанному диапазону
    if (req.method == "PURGE") {
        # Если запрос не из списка, то разворачивать
        if (!client.ip ~ purge) {
            return(synth(405, "This IP is not allowed to send PURGE requests."));
        }
        return (purge);
    }

    # POST-запросы а также страницы с Basic-авторизацией пропускать
    if (req.http.Authorization || req.method == "POST") {
        return (pass);
    }

    # Пропускать админку и страницу входа
    if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
        return (pass);
    }

    # Пропускать sitemap и файл robots, у меня sitemap генерируется плагином Google XML Sitemaps
    if (req.url ~ "sitemap" || req.url ~ "robots") {
        return (pass);
    }

    # Удаляем cookies, содержащие "has_js" и "__*", добавляемые CloudFlare и Google Analytics, так как Varnish не будет кэшировать запросы, для которых установлены cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");

    # Удаление префикса ";" в cookies, если вдруг будет обнаружен
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

    # Удаляем Quant Capital cookies (добавляются некоторыми плагинами)
    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
    # Удаляем wp-settings-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

    # Удаляем wp-settings-time-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

    # Удаляем wp test cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

    # Удаляем cookie, состоящие только из пробелов (или вообще пустые)
    if (req.http.cookie ~ "^ *$") {
            unset req.http.cookie;
    }

    # Для статических документов удаляем все cookies, пусть себе кэшируются 
    if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico|woff|svg|htm|html)") {
        unset req.http.cookie;
    }

    # Если установлены cookies "wordpress_" или "comment_" пропускаем напряиую к бэкенду
    if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
        return (pass);
    }

    # Если cookie не найдено, удаляем данный параметр из пришедшего запроса как таковой
    if (!req.http.cookie) {
        unset req.http.cookie;
    }

    # Не кэшировать запросы с установленными cookies, это уже не касается WordPress
    if (req.http.Authorization || req.http.Cookie) {
        # Not cacheable by default
        return (pass);
    }

    # Кэшировать всё остальное
    return (hash);
}

sub vcl_pass {
    return (fetch);
}

sub vcl_hash {
    hash_data(req.url);

    return (lookup);
}

# Приём ответа от бэкенда
sub vcl_backend_response {
    # Удаляем ненужные заголовки
    unset beresp.http.Server;
    unset beresp.http.X-Powered-By;

    # Не хранить в кэше robots и sitemap
    if (bereq.url ~ "sitemap" || bereq.url ~ "robots") {
        set beresp.uncacheable = true;
        set beresp.ttl = 30s;
        return (deliver);
    }

    # Для статических файлов, которые отдаёт бэкенд...
    if (bereq.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico|woff|svg|htm|html") {
        # Удаляем все куки 
        unset beresp.http.cookie;
        # Устанавливаем срок хранения в кэше - неделю
        set beresp.ttl = 7d;
        # Устанавливаем заголовки Cache-Control и Expires, сообщая браузеру о том, что эти файлы стоит сохранить в кэше клиента и не нагружать лишниий раз наш сервер
        unset beresp.http.Cache-Control;
        set beresp.http.Cache-Control = "public, max-age=604800";
        set beresp.http.Expires = now + beresp.ttl;
    }

    # Не кэшировать админку и страницу логина
    if (bereq.url ~ "wp-(login|admin)" || bereq.url ~ "preview=true") {
        set beresp.uncacheable = true;
        set beresp.ttl = 30s;
        return (deliver);
    }

    # Разрешить устанавливать куки только при обращении к этим путям, всё остальное будет резаться
        if (!(bereq.url ~ "(wp-login|wp-admin|preview=true)")) {
        unset beresp.http.set-cookie;
    }

    # Не кэшировать результат ответа на POST-запрос или Basic авторизации
    if ( bereq.method == "POST" || bereq.http.Authorization ) {
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    }

    # Не кэшировать результаты поиска
    if ( bereq.url ~ "\?s=" ){
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    }

    # Не кэшировать страницы ошибок, только нужные вещи в кэше!
    if ( beresp.status != 200 ) {
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    }

    # Хранить в кэше всё прочее на протяжении одного дня
    set beresp.ttl = 1d;
    # Срок жизни кэша после истечения его TTL
    set beresp.grace = 30s;

    return (deliver);
}

# Действия перед отдачей результата пользователю
sub vcl_deliver {
    # Удаляем ненужные заголовки
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    unset resp.http.Via;
    unset resp.http.X-Varnish;

    return (deliver);
}

Бэкенд запускаем на http://127.0.0.1:81, с фронтенда проксируем на Varnish: http://127.0.0.1:6081/

Перезапускаем Varnish:

service varnish restart

Готово, страница на сервере генерируется в 10 раз быстрее.

Присоединяйтесь к нам в ВКонтакте и в Facebook, чтобы не пропустить новые уроки. А также вступайте в наш чат PHP-разработчиков в Telegram.
Об авторе
Артём Ивашкевич
Артём Ивашкевич
Занимаюсь программированием более трех лет. В свободное время обучаю программированию на PHP других людей, потому что мне это нравится. Если вы интересуетесь темой IT и хотели бы стать разработчиком, рекомендую прочитать статью о том, как я стал программистом.
Самый понятный курс PHP
Онлайн-уроки в удобное время!
Начать бесплатно
Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно
Комментарии (0)
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
loader
Есть вопрос по программированию?
Здесь быстро ответят!
Задать вопрос
Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно
loader
Форум веб-разработчиков
Здесь все!
Перейти
loader
Логические задачи с собеседований