如何指示Varnish基于响应标头进行缓存



我有一系列关于网站上各种URL的视频。我想用Varnish缓存它们,,即使用户登录。我可以使用VCL配置来将某些URL列入白名单进行缓存。但我不知道如何将所有视频列入白名单。

有没有一种方法可以说,所有返回的内容类型为video/mp4的响应都被缓存了?

在Varnish中,决定从缓存中提供对象和决定将对象存储在缓存中是两件不同的事情。这两种情况都需要考虑在内。

内置VCL

为了了解开箱即用的情况,您需要查看以下VCL文件:https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl

这是执行的内置VCL。对于每个子例程,当您没有在VCL文件中为相应的子例程执行显式return(xyz)时,就会执行此逻辑。

这意味着你有某种安全网来保护你。

从技术角度来看,在将VCL文件编译成C代码之前,Varnish编译器会将内置的VCL部分添加到您在VCL中扩展的子例程中。

我们从内置的VCL中学到了什么

当谈到可缓存性时,内置的VCL教会了我们以下几点:

  • Varnish将仅为GETHEAD请求的缓存中的对象提供(请参阅vcl_recv)
  • 如果存在CookieAuthorization标头,Varnish将不会从缓存中提供对象(请参阅vcl_recv)
  • 如果存在Set-Cookie标头,Varnish将不会在缓存中存储对象(请参阅vcl_backend_response)
  • 如果TTL为零或小于,Varnish将不会在缓存中存储对象(请参阅vcl_backend_response)
  • 如果Cache-Control标头包含no-store,Varnish将不会在缓存中存储对象(请参见vcl_backend_response)
  • 如果Surrogate-Control标头包含no-cacheno-storeprivate,则Varnish不会在缓存中存储对象(请参见vcl_backend_response)
  • 如果Vary标头通过*对所有标头执行缓存变化,则Varnish不会将对象存储在缓存中(请参见vcl_backend_response)

如何确保从缓存提供视频文件

vcl_recv中,您必须确保Varnish愿意从缓存中查找视频请求。实际上,这意味着要注意cookie。

我的建议是删除所有的cookie,除了你真正需要的cookie。下面的示例将删除除PHPSESSIDcookie之外的所有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处理的。

当未设置PHPSESSIDcookie时,vcl_recv将回退到内置VCL上,并且请求将从缓存中提供。

但在您的情况下,即使用户登录,您也希望从缓存中提供视频。这很好,因为视频是不受状态影响的静态文件。

问题是在请求上下文中无法指定Content-Type信息。您必须使用URL。

举个例子:

sub vcl_recv {
if(req.url ~ "^/video") {
return(hash);
}
}

如果URL与^/video正则表达式模式匹配,此代码段将绕过内置的VCL,并在缓存中显式查找对象。

如何确保视频文件存储在缓存中

当您在vcl_recv中执行显式return(hash)时,将创建哈希并进行缓存查找。但是,如果对象没有存储在缓存中,您仍然会有一个未命中,这将导致后端请求。

当后端响应返回时,它需要在缓存中存储一定的时间。考虑到内置的VCL,您必须确保没有指定零TTL,并且Cache-Control响应标头必须返回可缓存的语法。

例如,如果我们想缓存一天的视频文件,我会这样设置Cache-Control标头:

Cache-Control: public, max-age=86400

Varnish将尊重此标头,并根据max-age语法将TTL设置为1天。

即使您没有指定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,并显式存储和传递对象。仅当Content-Type响应标头以image/或以video/开始时才出现这种情况

最新更新