#caching #varnish
#кэширование #varnish
Вопрос:
У меня есть серия видеороликов по различным URL-адресам на сайте. Я хотел бы кэшировать их все с помощью Varnish, даже если пользователь вошел в систему. Я могу использовать конфигурацию VCL, чтобы внести в белый список определенные URL-адреса для кэширования. Но я не знаю, как я могу внести все видео в белый список.
Есть ли способ сказать, что все ответы, которые возвращаются с типом контента video / mp4, кэшируются?
Ответ №1:
Решение обслуживать объект из кэша и решение сохранить объект в кэше — это 2 разные вещи в Varnish. Необходимо учитывать обе ситуации.
Встроенный VCL
Чтобы понять, что происходит «из коробки», вам нужно взглянуть на следующий файл VCL: https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl
Это встроенный VCL, который выполняется. Для каждой подпрограммы эта логика выполняется, когда вы не выполняете явное return(xyz)
в вашем файле VCL для соответствующей подпрограммы.
Это означает, что у вас есть какая-то система безопасности для защиты.
С технической точки зрения компилятор Varnish добавит встроенные части VCL к подпрограммам, которые вы расширяете в своем VCL, перед компиляцией файла VCL в код C.
Что мы узнаем из встроенного VCL
Встроенный VCL учит нас следующим вещам, когда дело доходит до кэширования:
- Varnish будет обслуживать только объект из кэша для
GET
HEAD
запросов и (см.vcl_recv
) - Varnish не будет обслуживать объект из кэша, если
Cookie
Authorization
присутствует заголовок or (см.vcl_recv
) - Varnish не сохранит объект в кэше, если
Set-Cookie
присутствует заголовок (см.vcl_backend_response
) - Varnish не сохранит объект в кэше, если TTL равен нулю или меньше (см.
vcl_backend_response
) - Varnish не сохранит объект в кэше, если
Cache-Control
заголовок содержитno-store
(см.vcl_backend_response
) - Varnish не сохранит объект в кэше, если
Surrogate-Control
заголовок содержитno-cache
no-store
илиprivate
(см.vcl_backend_response
) - Varnish не сохранит объект в кэше, если
Vary
заголовок выполняет изменения кэша для всех заголовков через*
(см.vcl_backend_response
)
Как убедиться, что видеофайлы передаются из кэша
В vcl_recv
вы должны убедиться, что Varnish готов выполнять поиск видеозапросов из кэша. На практике это означает заботу о файлах cookie.
Мой совет — удалить все файлы cookie, кроме тех, которые вам действительно нужны. В приведенном ниже примере будут удалены все файлы cookie, кроме файла PHPSESSID
cookie, который требуется моему бэкэнду:
vcl 4.1;
sub vcl_recv {
if (req.http.Cookie) {
set req.http.Cookie = ";" req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; ", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; 1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ] |[; ] $", "");
if (req.http.cookie ~ "^s*$") {
unset req.http.cookie;
}
}
Этот пример удалит файлы cookie отслеживания из запроса, что нормально, потому что они обрабатываются Javascript.
Когда файл PHPSESSID
cookie не установлен, vcl_recv
он возвращается к встроенному VCL, и запрос будет отправлен из кэша.
Но в вашем случае вы хотите, чтобы они обслуживались из кэша, даже когда пользователи вошли в систему. Это нормально, потому что видео — это статические файлы, на которые не влияет состояние.
Проблема в том, что в контексте запроса вы не можете указать Content-Type
информацию. Вам придется использовать URL.
Вот пример:
sub vcl_recv {
if(req.url ~ "^/video") {
return(hash);
}
}
Этот фрагмент будет обходить встроенный VCL и явно искать объект в кэше, если URL-адрес соответствует шаблону ^/video
регулярных выражений.
Как убедиться, что видеофайлы хранятся в кэше
Когда вы выполняете явный return(hash)
vcl_recv
ввод, будет создан хэш и будет выполнен поиск в кэше. Но если объект не сохранен в кэше, у вас все равно будет ошибка, что приведет к внутреннему запросу.
Когда серверный ответ возвращается, его необходимо сохранить в кэше в течение определенного времени. Учитывая встроенный VCL, вы должны убедиться, что вы не указали нулевой TTL, а заголовок Cache-Control
ответа должен возвращать кэшируемый синтаксис.
Вот как я бы установил Cache-Control
заголовок, если, например, мы хотим кэшировать видеофайлы в течение дня:
Cache-Control: public, max-age=86400
Varnish будет учитывать этот заголовок и установит TTL равным 1 дню на основе max-age
синтаксиса.
Даже если вы не укажете Cache-Control
заголовок, Varnish все равно сохранит его в кэше, но на 2 минуты, что является TTL по умолчанию.
Вот пример, в котором Varnish не будет сохранять объект в кэше на основе Cache-Control
заголовка:
Cache-Control: private, max-age=0, s-maxage=0 ,no-cache, no-store
Если любое из этих выражений Cache-Control
включено, Varnish сделает объект недоступным для кэширования.
Если Set-Cookie
заголовки являются частью ответа, объект также становится недоступным для кэширования.
В случае, если у вас нет полного контроля над заголовками, которые возвращаются внутренним сервером, вы все равно можете испытать свою удачу в VCL.
Вот фрагмент VCL, в котором мы принудительно сохраняем объекты в кэше для изображений и видео:
sub vcl_backend_response {
if(beresp.http.Content-Type ~ "^(image|video)/") {
set beresp.ttl = 1d;
unset beresp.http.set-cookie;
return (deliver);
}
}
В этом примере будут удалены Set-Cookie
заголовки, переопределен TTL для a day, и он явно сохранит и доставит объект. Это только в том случае, когда заголовки Content-Type
ответов начинаются либо с image/
, либо с video/