[英]How do I instruct Varnish to cache based on response header?
I have a series of videos on various URLs across the site.我在整个站点的各种 URL 上有一系列视频。 I would like to cache them all with Varnish, even if the user is logged in .
我想用 Varnish 缓存它们,即使用户已登录。 I can use the VCL configuration in order to whitelist certain URLs for caching.
我可以使用 VCL 配置将某些 URL 列入白名单以进行缓存。 But I don't know how I can whitelist all videos.
但我不知道如何将所有视频列入白名单。
Is there a way to say that all responses that return with a content type of video/mp4 are cached?有没有办法说所有返回内容类型为 video/mp4 的响应都被缓存了?
Deciding to serve an object from cache, and deciding to store an object in cache are 2 different things in Varnish.决定从缓存中提供 object 和决定在缓存中存储 object 在 Varnish 中是两件不同的事情。 Both situations need to be accounted for.
这两种情况都需要考虑。
In order to understand what happens out-of-the-box, you need to have a look at the following VCL file: https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin.vcl为了了解开箱即用的情况,您需要查看以下 VCL 文件: https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishd/builtin。 vcl
This is the built-in VCL that is executed.这是执行的内置 VCL。 For each subroutine this logic is executed when you don't do an explicit
return(xyz)
in your VCL file for the corresponding subroutine.对于每个子例程,当您没有在 VCL 文件中为相应的子例程执行显式
return(xyz)
时,将执行此逻辑。
This means you have some sort of safety.net to protect you.这意味着您有某种 safety.net 来保护您。
From a technical perspective, the Varnish Compiler will add the built-in VCL parts to the subroutines you extend in your VCL prior to compiling the VCL file into a C code.从技术角度来看,在将 VCL 文件编译成 C 代码之前,Varnish 编译器会将内置的 VCL 部分添加到您在 VCL 中扩展的子例程中。
The built-in VCL teaches us the following things when it comes to cacheability:内置的 VCL 告诉我们以下关于可缓存性的知识:
GET
and HEAD
requests (see vcl_recv
) GET
和HEAD
请求提供 object (参见vcl_recv
)Cookie
or Authorization
header is present (see vcl_recv
)Cookie
或Authorization
header,清漆将不会从缓存中提供 object (请参阅vcl_recv
)Set-Cookie
header is present (see vcl_backend_response
)Set-Cookie
header,清漆将不会在缓存中存储 object (请参阅vcl_backend_response
)vcl_backend_response
)vcl_backend_response
)Cache-Control
header contains no-store
(see vcl_backend_response
)Cache-Control
header 包含no-store
,则 Varnish 不会将 object 存储在缓存中(参见vcl_backend_response
)Surrogate-Control
header contains no-cache
, no-store
or private
(see vcl_backend_response
)Surrogate-Control
header 包含no-cache
、 no-store
或private
(参见vcl_backend_response
) ,Varnish 将不会在缓存中存储 objectVary
header performs cache variations on all headers via a *
(see vcl_backend_response
)Vary
header 通过*
对所有标头执行缓存变化,则 Varnish 不会将 object 存储在缓存中(请参阅vcl_backend_response
)In vcl_recv
you have to make sure Varnish is willing to lookup video requests from cache.在
vcl_recv
中,您必须确保 Varnish 愿意从缓存中查找视频请求。 In practical terms, this means taking care of the cookies.实际上,这意味着要处理 cookies。
My advice would be to remove all cookies, except the ones you really need.我的建议是删除所有 cookies,除了你真正需要的那些。 The example below will remove all cookies, except the
PHPSESSID
cookie, which is required by my backend:下面的示例将删除所有 cookies,但我的后端需要的
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;
}
}
This example will remove tracking cookies from the request, which is fine, because they are processed by Javascript.此示例将从请求中删除跟踪 cookies,这很好,因为它们由 Javascript 处理。
When the PHPSESSID
cookie is not set, vcl_recv
will fall back on the built-in VCL , and the request will be served from cache.当未设置
PHPSESSID
cookie 时, vcl_recv
将退回到内置 VCL ,请求将从缓存中获取。
But in your case, you want them to be served from cache, even when users are logged in. This is fine, because videos are static files that aren't influenced by state.但在您的情况下,您希望从缓存中提供它们,即使用户已登录。这很好,因为视频是不受 state 影响的 static 文件。
The problem is that in the request context you cannot specify Content-Type
information.问题是在请求上下文中您不能指定
Content-Type
信息。 You'll have to use the URL.您必须使用 URL。
Here's example:这是例子:
sub vcl_recv {
if(req.url ~ "^/video") {
return(hash);
}
}
This snippet will bypass the built-in VCL , and will explicitly look the object up in cache, if the URL matches the ^/video
regex pattern.此代码段将绕过内置 VCL ,如果 URL 与
^/video
正则表达式模式匹配,则会在缓存中明确查找 object。
When you do an explicit return(hash)
in vcl_recv
, the hash will be created and a cache lookup takes place.当您在
vcl_recv
中执行显式return(hash)
时,将创建 hash 并进行缓存查找。 But if the object is not stored in cache, you'll still have a miss, which results in a backend request.但是如果 object 没有存储在缓存中,你仍然会错过,这会导致后端请求。
When the backend response comes back, it needs to be stored in cache for a certain amount of time.当后端响应返回时,需要在缓存中保存一定时间。 Given the built-in VCL , you have to make sure you don't specify a zero-TTL, and the
Cache-Control
response header must return cacheable syntax.给定内置 VCL ,您必须确保未指定零 TTL,并且
Cache-Control
响应 header 必须返回可缓存语法。
This is how I would set the Cache-Control
header if for example we want to cache video files for a day:例如,如果我们想要缓存一天的视频文件,这就是我设置
Cache-Control
header 的方式:
Cache-Control: public, max-age=86400
Varnish will respect this header, and will set the TTL to 1 day based on the max-age
syntax. Varnish 会尊重这个 header,并会根据
max-age
语法将 TTL 设置为 1 天。
Even if you don't specify a Cache-Control
header, Varnish will still store it in cache, but for 2 minutes, which is the default TTL.即使您不指定
Cache-Control
header,Varnish 仍会将其存储在缓存中,但持续时间为 2 分钟,这是默认的 TTL。
Here's an example where Varnish will not store the object in cache, based on the Cache-Control
header:这是一个 Varnish 不会将 object 存储在缓存中的示例,基于
Cache-Control
header:
Cache-Control: private, max-age=0, s-maxage=0 ,no-cache, no-store
If either of these expressions is in Cache-Control
, Varnish will make the object uncacheable.如果这些表达式中的任何一个在
Cache-Control
中,Varnish 将使 object 不可缓存。
If Set-Cookie
headers are part of the response, the object becomes uncacheable as well.如果
Set-Cookie
标头是响应的一部分,则 object 也变得不可缓存。
In case you don't have full control over the headers that are returned by the backend server, you can still force your luck in VCL.如果您不能完全控制后端服务器返回的标头,您仍然可以在 VCL 中靠运气。
Here's a VCL snippet where we force objects to be stored in cache for images and videos:这是一个 VCL 片段,我们强制将对象存储在图像和视频的缓存中:
sub vcl_backend_response {
if(beresp.http.Content-Type ~ "^(image|video)/") {
set beresp.ttl = 1d;
unset beresp.http.set-cookie;
return (deliver);
}
}
This example will strip off Set-Cookie
headers, will override the TTL to a day, and it will explicitly store and deliver the object. This is only the case when the Content-Type
response headers either starts with image/
, or with video/
此示例将剥离
Set-Cookie
标头,将 TTL 覆盖为一天,并将显式存储和传送 object。仅当Content-Type
响应标头以image/
或以video/
开头时才会出现这种情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.