清漆缓存和 headers
Varnish Cache and headers
我正在尝试缓存我的网络应用程序的特定部分。
我在 http://website.dev/pictures/:id
有一个端点,returns PHP 生成图片。有时,端点可以在查询字符串中带有宽度和高度来定义图片尺寸:http://website.dev/pictures/:id?w=100&h=100
。
所以我想将这些请求缓存很长时间。
我尝试了一个非常简单的 VCL,因为我是新手,我不想做复杂的事情:
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "^/api/pictures" && req.method ~ "GET") {
# I heard that it was better to unset the cookies here to allow cache
unset req.http.cookie;
return (hash);
}
return (pass);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
但是现在,我的请求都被 MISS 了。我试图修改来自我的后端的响应以获得适当的 cache-control 并过期 headers:
Response Headers:
Accept-Ranges:bytes
Age:0
Cache-Control:max-age=10000, private
Connection:keep-alive
Content-Length:96552
Content-Type:image/jpeg
Date:Sun, 30 Jul 2017 16:41:58 GMT
Expires:Fri, 01 Jan 2100 00:00:00 GMT
Server:nginx/1.10.3 (Ubuntu)
Via:1.1 varnish (Varnish/5.1)
X-Cache:MISS
X-RateLimit-Limit:60
X-RateLimit-Remaining:57
X-Varnish:32772
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
Cache-Control:max-age=0
Connection:keep-alive
Cookie:_ga=xxxxxxxxxxxxx
Host:website.dev:6081
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
我哪里错了?我如何确保此类端点上的请求仅由 Varnish 缓存很长时间?
它没有按预期缓存的原因是因为您的网络应用程序正在发送:
Cache-Control:max-age=10000, private
built-in VCL 逻辑prevents caching in presence of Cache-Control: private
。
这里最好的做法是修复您的应用程序:要么坚持使用 Cache-Control
和 public 类型,要么删除它并保留只有 Expires
header.
如果您不愿意修复应用程序或有理由不这样做,则需要添加一些 VCL。以下将确保上面提到的 "built-in VCL logic" 不会阻止存在 Cache-Control: private
的缓存:
sub vcl_backend_response {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store") ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
return (deliver);
}
最后,当您的应用程序发送适当的 Expires
header 用于缓存时,它会被 Varnish 忽略,因为 Cache-Control
header 优先于它。 (根据 HTTP 规范)。请注意它,因为它的值将用作 Varnish 缓存 object 的持续时间。 (而不是来自 Expires
的值)
我正在尝试缓存我的网络应用程序的特定部分。
我在 http://website.dev/pictures/:id
有一个端点,returns PHP 生成图片。有时,端点可以在查询字符串中带有宽度和高度来定义图片尺寸:http://website.dev/pictures/:id?w=100&h=100
。
所以我想将这些请求缓存很长时间。
我尝试了一个非常简单的 VCL,因为我是新手,我不想做复杂的事情:
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "^/api/pictures" && req.method ~ "GET") {
# I heard that it was better to unset the cookies here to allow cache
unset req.http.cookie;
return (hash);
}
return (pass);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
但是现在,我的请求都被 MISS 了。我试图修改来自我的后端的响应以获得适当的 cache-control 并过期 headers:
Response Headers:
Accept-Ranges:bytes
Age:0
Cache-Control:max-age=10000, private
Connection:keep-alive
Content-Length:96552
Content-Type:image/jpeg
Date:Sun, 30 Jul 2017 16:41:58 GMT
Expires:Fri, 01 Jan 2100 00:00:00 GMT
Server:nginx/1.10.3 (Ubuntu)
Via:1.1 varnish (Varnish/5.1)
X-Cache:MISS
X-RateLimit-Limit:60
X-RateLimit-Remaining:57
X-Varnish:32772
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
Cache-Control:max-age=0
Connection:keep-alive
Cookie:_ga=xxxxxxxxxxxxx
Host:website.dev:6081
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
我哪里错了?我如何确保此类端点上的请求仅由 Varnish 缓存很长时间?
它没有按预期缓存的原因是因为您的网络应用程序正在发送:
Cache-Control:max-age=10000, private
built-in VCL 逻辑prevents caching in presence of Cache-Control: private
。
这里最好的做法是修复您的应用程序:要么坚持使用 Cache-Control
和 public 类型,要么删除它并保留只有 Expires
header.
如果您不愿意修复应用程序或有理由不这样做,则需要添加一些 VCL。以下将确保上面提到的 "built-in VCL logic" 不会阻止存在 Cache-Control: private
的缓存:
sub vcl_backend_response {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store") ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
return (deliver);
}
最后,当您的应用程序发送适当的 Expires
header 用于缓存时,它会被 Varnish 忽略,因为 Cache-Control
header 优先于它。 (根据 HTTP 规范)。请注意它,因为它的值将用作 Varnish 缓存 object 的持续时间。 (而不是来自 Expires
的值)