Caching 如何根据响应头指示Varnish缓存?

Caching 如何根据响应头指示Varnish缓存?,caching,varnish,Caching,Varnish,我在整个网站的不同URL上有一系列视频。我想用Varnish来缓存它们,即使用户已经登录。我可以使用VCL配置将某些URL列为白名单以进行缓存。但我不知道如何将所有视频列入白名单 有没有一种方法可以说所有返回的内容类型为video/mp4的响应都被缓存了?决定从缓存中服务对象和决定将对象存储在缓存中是Varnish中的两件不同的事情。这两种情况都需要考虑 内置VCL 为了理解开箱即用的情况,您需要查看以下VCL文件: 这是执行的内置VCL。对于每个子例程,当您没有在VCL文件中为相应的子例程执行

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


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

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

内置VCL 为了理解开箱即用的情况,您需要查看以下VCL文件:

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

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

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

我们从内置VCL中学到了什么 在可缓存性方面,内置VCL教会我们以下几点:

  • Varnish将仅为
    GET
    HEAD
    请求的缓存对象提供服务(请参见
    vcl\u recv
  • 如果存在
    Cookie
    Authorization
    标头,Varnish将不会为缓存中的对象提供服务(请参见
    vcl\U recv
  • 如果存在
    Set Cookie
    头,Varnish将不会在缓存中存储对象(请参阅
    vcl\u backend\u response
  • 如果TTL为零或更小,Varnish将不会在缓存中存储对象(请参见
    vcl\u backend\u response
  • 如果
    缓存控件
    标头包含
    无存储
    (请参阅
    vcl\u后端\u响应
    ),则Varnish不会在缓存中存储对象
  • 如果
    代理控件
    标头包含
    无缓存
    无存储
    私有
    (请参阅
    vcl\u后端\u响应
    ),则Varnish不会将对象存储在缓存中
  • 如果
    Vary
    标头通过
    *
    对所有标头执行缓存变体,则Varnish不会将对象存储在缓存中(请参阅
    vcl\u后端\u响应
如何确保从缓存中提供视频文件 在
vcl\u recv
中,您必须确保Varnish愿意从缓存中查找视频请求。实际上,这意味着要照顾好饼干

我的建议是删除所有cookies,除了你真正需要的cookies。下面的示例将删除所有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\u recv
将回退到内置vcl上,请求将从缓存中提供

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

问题在于,在请求上下文中,不能指定
内容类型
信息。您必须使用URL

下面是一个例子:

sub vcl_recv {
    if(req.url ~ "^/video") {
        return(hash);
    }
}
如果URL与
^/video
regex模式匹配,此代码段将绕过内置VCL,并在缓存中显式查找对象

如何确保视频文件存储在缓存中 在
vcl\u recv
中执行显式
返回(哈希)
时,将创建哈希并进行缓存查找。但是,如果对象未存储在缓存中,您仍然会丢失,这将导致后端请求

当后端响应返回时,它需要存储在缓存中一段时间。给定内置的VCL,您必须确保没有指定零TTL,并且
缓存控制
响应头必须返回可缓存语法

这就是我如何设置
缓存控制
标题的方法,例如,如果我们想缓存一天的视频文件:

Cache-Control: public, max-age=86400
Varnish将尊重此标题,并将根据
max age
语法将TTL设置为1天

即使您没有指定
缓存控件
头,Varnish仍会将其存储在缓存中,但存储时间为2分钟,这是默认的TTL

下面是一个示例,其中Varnish不会根据
缓存控制
标题将对象存储在缓存中:

Cache-Control: private, max-age=0, s-maxage=0 ,no-cache, no-store
如果这些表达式中的任何一个在缓存控制中,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覆盖为一天,并显式存储和传递对象。只有当
内容类型
响应标题以
图像/
视频/
开头时,才会出现这种情况