Как правильно настроить Varnish для сайтов Symfony2?

У меня есть веб-сайт (с ESI), который использует обратный прокси-сервер Symfony2 для кэширования. Среднее время отклика составляет около 100 мс. Я попытался установить Varnish на сервер, чтобы попробовать. Я шаг за шагом следовал руководству из кулинарной книги Symfony, удалил все в cache папка, но папка http_cache все еще была создана, когда я пробовал. Поэтому я решил, что могу попытаться закомментировать $kernel = new AppCache($kernel); из app.php. Это сработало очень хорошо. http_cache больше не создавался, и Varnish, похоже, работал:

12951         0.00         0.08 cache_hitpass - Cache hits for pass
 1153         0.00         0.01 cache_miss - Cache misses

Это было из примерно 14000 запросов, поэтому я думал, что все будет в порядке. Но после повторения я обнаружил, что ответы увеличились до ~ 2 секунд.

Apache работает на порту 9000, а Varnish на 8080. Поэтому я повторил, используя echoping -n 10 -h http://servername/ X.X.X.X:8080.

Я понятия не имею, что может быть не так. Требуются ли дополнительные настройки для использования Varnish с Symfony2? Или я просто что-то не так делаю?


По запросам, вот мой default.vcl с изменениями, которые я сделал до сих пор.

Я обнаружил 2 проблемы с конфигурацией Varnish по умолчанию:

  • он не кэширует запросы с помощью файлов cookie (и каждому в моем приложении назначен сеанс)
  • он игнорирует заголовок Cache-Control: no-cache

Поэтому я добавил условия для этих случаев в свою конфигурацию, и теперь она работает довольно хорошо (~ 175 запросов в секунду по сравнению с ~ 160 с обратным прокси-сервером S2 — но, честно говоря, я ожидал немного большего). Я просто понятия не имею, как проверить, все ли в порядке, поэтому любые входные данные приветствуются.

Кэш большинства страниц зависит от файла cookie, с s-maxage 1200. Обычные включения ESI не зависят от файла cookie, с довольно низким s-maxage (статьи, списки статей). Страницы профилей пользователей вообще не кэшируются (no-cache), и я не совсем уверен, что Varnish даже кэширует их в ESI. Только ESI, который изменяется с помощью файлов cookie, представляет собой заголовок с информацией о пользователе (это на 100% страниц).

Все в этом посте относится к Varnish 3.X (лично я использую 3.0.2).

Кроме того, после нескольких недель копания в этом, я действительно понятия не имею, что я делаю, поэтому, если вы найдете что-то странное в конфигах, просто дайте мне знать.

введите здесь описание изображения


person Ondrej Slinták    schedule 19.01.2012    source источник
comment
5 центов на основе моего недавнего опыта. Все очень зависит от конфигурации Vasnish ​​и особенно от того, достаточно ли у вас памяти для этого. Не могли бы вы показать свои sub vcl_recv, sub vcl_fetch и backend?   -  person Anton Babenko    schedule 20.01.2012
comment
Обновлен исходный пост с конфигами. Еще одна вещь, которая приходит мне на ум, это пользовательские куки (и, возможно, отслеживающие). Они есть в каждом запросе на нашей странице. Но я не понимаю, почему лакстат говорит, что тогда кэширует 90% запросов. У нас никогда не было проблем с ними, когда мы использовали обратный прокси Symfony2.   -  person Ondrej Slinták    schedule 20.01.2012
comment
У меня на сетапе есть похожие vcl_recv, хотя там тоже есть эти строчки: set req.http.X-Forwarded-Port = "80"; set req.http.X-Forwarded-Proto = "http";   -  person Anton Babenko    schedule 20.01.2012


Ответы (2)


Я удивлен, что за 10 месяцев не было действительно полного ответа. Это может быть действительно полезная страница.

Вы сами отметили, что:

  • Varnish не кэширует запросы с помощью файлов cookie.
  • Varnish игнорирует Cache-Control: заголовок no-cache

Во-первых, всем ли в вашем приложении нужен сеанс? Если нет, не начинайте сеанс или, по крайней мере, отложите его запуск до тех пор, пока это действительно необходимо (т. е. они не войдут в систему или что-то еще).

Если вы все еще можете кэшировать страницы, когда пользователи вошли в систему, вам нужно быть очень осторожным, чтобы не предоставить пользователю страницу, предназначенную для кого-то другого. Но если вы собираетесь это сделать, отредактируйте vcl_recv(), чтобы удалить cookie сеанса для страниц, которые вы хотите кэшировать.

Вы можете легко заставить Varnish обрабатывать директиву no-cache в vcl_fetch(), и на самом деле вы уже сделали это.

Еще одна проблема, которую я обнаружил, заключается в том, что Symfony по умолчанию устанавливает max-age на 0, что означает, что они никогда не будут кэшироваться логикой по умолчанию в vcl_fetch.

Я также заметил, что у вас в Varnish установлен порт:

backend default {
    .host = "127.0.0.1";
    .port = "80";
}

Вы сами сказали, что Apache работает на порту 9000, так что это не похоже. Обычно вы настраиваете Varnish для прослушивания порта по умолчанию (80) и настраиваете Varnish для поиска серверной части на порту 9000 или любом другом.

person exg    schedule 13.12.2012

Если это вся ваша конфигурация, vcl_recv настраивается дважды.

На страницах, которые вы хотите кэшировать, можете ли вы отправить заголовки кэширования? Это имело бы наибольший смысл, так как изображения, вероятно, уже имеют ваши заголовки кэширования apache, и логика приложения определяет страницы, которые могут быть фактически кэшированы, но вы также можете принудительно применить это в лаке.

Вы можете использовать vcl_recv следующим образом:

# Called after a document has been successfully retrieved from the backend.
sub vcl_fetch {

    # set minimum timeouts to auto-discard stored objects
    # set beresp.prefetch = -30s;
    set beresp.grace = 120s;

    if (beresp.ttl < 48h) {
      set beresp.ttl = 48h;}

    if (!beresp.cacheable) 
        {pass;}

    if (beresp.http.Set-Cookie) 
        {pass;}

    # if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") 
    # {pass;}

    if (req.http.Authorization && !beresp.http.Cache-Control ~ "public") 
        {pass;}

}

Этот кеширует в лаке только те запросы, которые установлены для кеширования. Также имейте в виду, что ваша конфигурация не кэширует запросы с файлами cookie.

person Rafael Sanches    schedule 03.02.2012
comment
Да, я думаю, что вся проблема была в куках. Сегодня я обновлю вопрос, добавив дополнительную информацию и события. - person Ondrej Slinták; 03.02.2012
comment
Ах, дерьмо, не заметил, что я два раза отправил recv вместо recv и fetch ›‹ - person Ondrej Slinták; 03.02.2012
comment
Отредактированный OP с дополнительной информацией под строкой. - person Ondrej Slinták; 03.02.2012
comment
Если вы хотите кэшировать запросы, содержащие файлы cookie, вы можете попробовать добавить что-то вроде этого в vcl_recv: unset req.http.cookie; - person Rafael Sanches; 03.02.2012