![为什么 Varnish 中的平均缓存命中率很低?](https://linux22.com/image/579345/%E4%B8%BA%E4%BB%80%E4%B9%88%20Varnish%20%E4%B8%AD%E7%9A%84%E5%B9%B3%E5%9D%87%E7%BC%93%E5%AD%98%E5%91%BD%E4%B8%AD%E7%8E%87%E5%BE%88%E4%BD%8E%EF%BC%9F.png)
有人知道为什么使用 Wordpress(使用 Varnish 和 Nginx)时平均缓存命中率非常低吗?
Varnish 统计数据显示:
命中率:10 100 518 命中率平均值:0.4143 0.2690 0.1948
知道如何修复此问题吗?我的 varnish default.vcl 是:
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
#
backend default {
.host = "77.81.240.177";
.port = "8080";
}
acl purge {
"77.81.240.177";
}
sub vcl_recv {
# Add a unique header containing the client address
remove req.http.X-Forwarded-For;
#set req.http.X-Forwarded-For = client.ip;
set req.http.X-Forwarded-For = req.http.rlnclientipaddr;
# Let's make sure we aren't compressing already compressed formats.
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|mp3|mp4|m4v)(\?.*|)$") {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.$", "");
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/$") {
unset beresp.http.set-cookie;
}
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
if (req.url ~ "^/w00tw00t") {
error 403 "Not permitted";
}
}
答案1
一个好的方法是用 varnishlog 检查流量以查看是什么使得哪些规则适用。
由于您没有强制执行 TTL,我猜测 wordpress 网站会提供 Cache-Control 标头,例如“max-age:0”或“no-cache”、“private”等,并且 varnish 会遵守此类标头,除非您明确告诉它不要这样做,即:
sub vcl_fetch {
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
set beresp.ttl = 3600s;
}
vcl_fetch 中的第一个规则没有意义,因为第二个规则将取消设置除 wp-login/wp-admin 之外的所有 URL 的所有 set-cookie。
向 vcl_deliver 添加一些配置以输出标头,说明是否命中:
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
return (deliver);
}
对您的配置的其他反馈:
在 vcl_recv 中,如果 url 不是 wp-login 或 wp-admin,则执行“unset req.http.cookie”,这意味着如果用户登录 /wp-login 然后转到“/”,您将取消设置他的 cookie。您只需要在 vcl_recv 中取消设置那些永远不需要 cookie 的 url,即 .(js|css|png|jpg) 等,并在 vcl_fetch 中删除设置的 cookie。
答案2
wp-varnish
查看wp-varnish- WordPress 的一个插件,当 WordPress 中的内容发生更改时,它会清除 Varnish 中的内容。它还附带一个示例 VCL,可以为您提供更好的命中率
示例 VCL
backend default {
.host = "127.0.0.1";
.port = "8080";
}
acl purge {
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
if(!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
return (pass);
}
remove req.http.cookie;
return (lookup);
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_fetch {
if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
return (hit_for_pass);
}
set beresp.ttl = 24h;
return (deliver);
}