09.10.2016   5016

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

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

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

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

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

Было — стало:

Устанавливаем 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 раз быстрее.

Комментарии

Чтобы написать комментарий нужно войти на сайт.
Или получить доступ прямо сейчас:


Нажимая эту кнопку
Вы принимаете политику конфиденциальности