我对 varnish 缓存世界还很陌生,我需要优化一个速度很慢的 Wordpress 应用程序。我今天做了很多研究,取得了一些进展,但我还是无法完成语言 cookie 的配置。
因此,应用程序设置了一个名为的 cookie qtrans_front_language
,用于指示前端需要使用哪种语言。我想用 varnish 缓存所有页面,但我不能忽略这个 cookie,否则在缓存页面后我无法切换语言,而且当同时从不同的浏览器导航时,我会出现奇怪的行为。
我考虑在缓存时将语言定义(例如“en”)添加到哈希中,以便每个页面都有自己的缓存条目,下次浏览时我会得到一个命中。
我的问题是这个 cookie 是由后端设置的,但是,如果我不“删除”后端 cookie,我的页面就永远不会被 varnish 缓存。
这是我目前所拥有的:
vcl 4.0;
# Import directors and std library.
import directors;
import std;
# Backend
backend default {
.host = "my_ip_here";
.port = "80";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
.max_connections = 800;
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
sub vcl_init {
new foo = directors.round_robin();
foo.add_backend(default);
}
sub vcl_recv {
call identify_cookie;
# Send all traffic to the foo director.
set req.backend_hint = foo.backend();
# Skip administrative areas
if (req.url ~ "wp-admin|wp-login|xmlrpc.php") {
return(pass);
}
# Do not cache POST requests.
if (req.http.Authorization || req.method == "POST") {
return(pass);
}
# Remove all cookies that starts with '__', namely Google Analytics cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
# Remove language cookie.
set req.http.Cookie = regsuball(req.http.Cookie, "qtrans_front_language=.*", "");
# Remove wordpress cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
# Remove empty cookies
set req.http.Cookie = regsuball(req.http.Cookie, "^ *$", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^; +?$", "");
# Cache images, css, js and other static content.
if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
unset req.http.cookie;
call normalize_req_url;
}
# Normalize Accept-Encoding header and compression
if (req.http.Accept-Encoding) {
# Do not compress compressed files.
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
unset 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 {
unset req.http.Accept-Encoding;
}
}
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
return(hash);
}
sub vcl_backend_response {
# Set a grace time of 1h
set beresp.grace = 1h;
# Set a TTL of 10m
set beresp.ttl = 10m;
# Avoid setting cookies and Cache-Control if url !~ wp-(login|admin)
if (!bereq.url ~ "wp-(login|admin)") {
unset beresp.http.Set-Cookie;
unset beresp.http.Cache-Control;
}
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (!req.http.Language) {
set req.http.Language = "en";
}
hash_data(req.http.Language);
# If the client supports compression, keep that in a different cache entry
if (req.http.Accept-Encoding) {
hash_data(req.http.Accept-Encoding);
}
return (lookup);
}
sub vcl_deliver {
# A bit of debugging info.
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
}
else {
set resp.http.X-Cache = "MISS";
}
}
sub vcl_hit {
# A cache hit, deliver it.
if (obj.ttl >= 0s) {
return(deliver);
}
# If object is in grace deliver it and trigger a background fetch.
# Also make sure backend is healthy.
if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
return(deliver);
}
else {
return(fetch);
}
}
# This method is used to strip out ?timestamp=[0-9]+ from the url
# so that we can hash it later.
sub normalize_req_url {
if (req.url ~ "\?timestamp=[0-9]+") {
set req.url = regsuball(req.url, "\?timestamp=[0-9]+", "");
}
}
sub identify_cookie {
if (req.http.cookie ~ "qtrans_front_language=") {
set req.http.Language = regsub(req.http.Cookie, "(.*?)(qtrans_front_language=)([^;]*)(.*)$", "\3");
}
}
因此,我能够检测到当前语言,但我做错了,因为即使用户设置了其他语言,也会提供错误的页面。我认为beresp.http.Set-Cookie
在后端响应中取消设置可能是错误的做法。
我做错了什么?我该如何解决这个问题?