Varnish 配置建议

Varnish 配置建议

我的 VPS 出现了一些问题。它出现了一些问题,而我的主机无法确定,因此我不得不经历一番艰辛,尝试重新配置一些东西。其中之一就是 Varnish... 我在这里发布了一个问题:https://webmasters.stackexchange.com/questions/89506/http-header-if-not-modified-help/89507?noredirect=1#comment109928_89507我使用 WP Super cache 创建页面的静态 HTML 文件,并使用 Mod_rewrite 来减少服务器负载。然后我将这些静态页面放入 Varnish 中,以进一步减少负载。

我遇到的问题是 WP Super cache 发送了一个 max-age=3,显然,3 秒后 Varnish 会将其记录为未命中,并持续 3 秒。所以,使用 Varnish 真的毫无意义。

但是,如果将内容的 max-age 设置为更长,意味着如果我在 WordPress 中更改 CSS 或动态页面,则浏览器中的内容会过时,这显然不是我想要的。

我想知道(如果这不是正确的方法,请纠正我)是否可以按照以下指南进行操作:https://www.varnish-cache.org/trac/wiki/VCLExampleLongerCachingVarnish 可以删除 WordPress 中 .htaccess 发送的标头,然后 Varnish 缓存一周(我猜,除非通过 SSH 或 WP HTTP 清除插件清除),并且浏览器缓存保持在 15 分钟的低位,所以如果有任何变化,它只会过期 15 分钟,但在那 15 分钟之后,下一个请求仍然来自 Varnish,而不是来自 Apache。

我负责的一些网站是摄影网站,因此我真的不想在 Varnish 中缓存 GB 级的图像,所以我目前已告诉我的 VCL 不要缓存这些图像。我只想缓存页面,这样我就可以摆脱 WordPress 使用的额外缓存插件。

我尝试过看看是否有办法延长 Varnish 的缓存时间,然后 WordPress 会发送一个标头,该标头会在浏览器中存储最长 1 天,但如果内容更新(例如网页或 CSS 文件),则会在浏览器中更新。我似乎还没有找到答案,所以也许我要求太多了。

这是我的VCL:

backend default {
  .host = "public IP";
  .port = "8080";
}

acl purge { "localhost"; "127.0.0.1";}

sub vcl_recv {
    if (req.request == "PURGE") {
    if (!client.ip ~ purge) {
    error 405 "Not allowed.";
    }
    return (lookup);
    }

#set req.grace = 60m;
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.http.Authorization || req.http.Cookie) { 
#return (pass); } 
return (lookup); 
# Set X-Forwarded-For header for logging in nginx
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;

# Remove has_js and CloudFlare/Google Analytics __* cookies and statcounter is_unique
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js|is_unique)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

# Either the admin pages or the login
if (req.url ~ "/wp-(login|admin|cron|cart|my-account|checkout|addons|administrator)") {
# Don't cache, pass to backend
return (pass);
}
if (req.url ~ "/administrator") {
  return (pass);
} 
if ( req.url ~ "\?add-to-cart=" ) {
 return (pass);
}
if (req.url ~ "/(contact-us|contact|get-a-quote|upload-files|competition)")
{
return(pass);
}
# Never cache PUT, PATCH, DELETE or POST requests 
#if (req.method == "PUT" || req.method == "PATCH" || req.method == "DELETE" || req.method == "POST") { 
#return (pass);
#} 
# Remove the wp-settings-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

# Remove the wp-settings-time-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, 
"wp-settings-time-1=[^;]+(; )?", "");

# Remove the wp test cookie
set req.http.Cookie = regsuball(req.http.Cookie, 
"wordpress_test_cookie=[^;]+(;)?", "");

# Static content unique to the theme can be cached (so no user uploaded images)
# The reason I don't take the wp-content/uploads is because of cache size on bigger blogs
# that would fill up with all those files getting pushed into cache
if (req.url ~ "lib/themes/" && req.url ~ 
"\.(css|js|png|gif|jp(e)?g)") {
unset req.http.cookie;
}

# Even if no cookies are present, I don't want my "uploads" to be cached due to their potential size
if (req.url ~ "/lib/uploads/") {
return (pass);
}

# any pages with captchas need to be excluded
if (req.url ~ "^/contact/" || req.url ~ "^/links/domains-for-sale/")
{
return(pass);
}

# Check the cookies for wordpress-specific items
if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
# A wordpress specific cookie has been set
return (pass);
}

# allow PURGE from localhost
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}

# Force lookup if the request is a no-cache request from the client
if (req.http.Cache-Control ~ "no-cache") {
return (pass);
}

# Try a cache-lookup
return (lookup);

}

sub vcl_fetch {
#set obj.grace = 5m;
#set beresp.grace = 60m;

}

sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}

sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}


sub vcl_deliver {
# multi-server webfarm? set a variable here so you can check
# the headers to see which frontend served the request
#   set resp.http.X-Server = "server-01";
   if (obj.hits > 0) {
     set resp.http.X-Cache = "HIT";
   } else {
     set resp.http.X-Cache = "MISS";
   }
}

因此目前,Varnish 清除需要 5 分钟,但我在网站 .htaccess 中的最大期限为 3 秒,这毫无意义。

我的想法正确吗?希望我说得有道理。希望有人能给我指明方向!

谢谢!

答案1

由于您使用的是 Varnish,我建议您在后端删除自定义 .htaccess 缓存标头,并从 Varnish 内部控制缓存标头。Varnish 网站上的 VCLExampleLongerCaching 示例应该可以为您正确完成此操作。

我发现 curl 对于向网站发出测试请求以查看返回的缓存标头非常有用。您可以执行此操作以仅查看给定请求返回的标头:

curl -s -D - http://www.example.com -o /dev/null

我曾尝试查看是否有办法延长 Varnish 的缓存时间,然后 WordPress 会发送一个标头,该标头会在浏览器中存储最长 1 天,但如果内容更新(例如网页或 CSS 文件),那么这将在浏览器中更新。

这是一个非常常见的要求,许多网站通过在页面源代码中每个 CSS/JS 文件的 URL 末尾添加一个唯一的哈希来处理它。每次文件更改时,唯一哈希也会更改,因此该资产现在有一个新的未缓存的 URL。因此,您只需从 Varnish 中清除 HTML 页面,对引用资产的任何更改都会自动更新。看来 Wordpress 也使用了这种技术 - 我刚刚查看了一个随机的 Wordpress 网站,发现源中每个 CSS 文件的末尾都有日期字符串,如“?v=20150727”。

相关内容