我已设置一台使用 Varnish 作为负载均衡器的服务器和两台运行 nginx/unicorn/sinatra 的服务器用于演示目的。所有三台服务器均可访问!我的 varnish vcl 文件:
backend web2 {
.host = "10.169.42.243";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
backend web1 {
.host = "10.47.137.196";
.port = "80";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
director demo round-robin {
{ .backend = web1; }
{ .backend = web2; }
}
sub vcl_recv {
set req.backend = demo;
}
健康检查对两个后端都同样有用:
0 Backend_health - web1 Still healthy 4--X-RH 5 3 5 0.004336 0.003621 HTTP/1.1 200 OK
0 Backend_health - web2 Still healthy 4--X-RH 5 3 5 0.003388 0.004753 HTTP/1.1 200 OK
我的 Sinatra 应用程序仅显示主机的 IP:需要“rubygems”需要“sinatra/base”需要“socket”
class MyApp < Sinatra::Base
get '/' do
headers \
"Cache-Control" => "no-cache, no-store, must-revalidate",
"Pragma" => "no-cache",
"Expires" => "0"
'Hello, nginx and unicorn! - ' + Socket.gethostname
end
end
但是当我访问负载均衡器的地址时,总是显示相同的 IP 地址。我可以手动访问两个后端并查看它们的唯一 IP。
我是否忽略了一些显而易见的事情?
编辑:我也尝试curl
过从 Varnish 机器上进行操作,可以看到后端的正确响应。关闭其中一个 Web 服务器时,Varnish 将使用另一个。但这不是应该在每个请求上都发生吗?
编辑 2:好的,我通过 nginx access_log 文件进行了更多调查,我发现 Varnish 不会对每个请求进行新的查找。对于给定的标头,我认为 Varnish 不会缓存内容。这里的错误是什么?
答案1
你没有提到你使用的是哪个版本的 Varnish。如果我没记错的话,Varnish 并不总是尊重Cache-Control
header。当前的内置的vcl但确实检查了标题。
尝试将以下内容添加到您的内容中default.vcl
,看看是否有所不同:
sub vcl_fetch {
# Varnish determined the object was not cacheable
if (!(beresp.ttl > 0s)) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
return(hit_for_pass);
}
elseif (req.http.Cookie) {
set beresp.http.X-Cacheable = "NO:Got cookie";
return(hit_for_pass);
}
elseif (beresp.http.Cache-Control ~ "private") {
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(hit_for_pass);
}
elseif (beresp.http.Cache-Control ~ "no-cache" || beresp.http.Pragma ~ "no-cache") {
set beresp.http.X-Cacheable = "Refetch forced by user";
return(hit_for_pass);
# You are extending the lifetime of the object artificially
}
elseif (beresp.ttl < 1s) {
set beresp.ttl = 5s;
set beresp.grace = 5s;
set beresp.http.X-Cacheable = "YES:FORCED";
# Varnish determined the object was cacheable
} else {
set beresp.http.X-Cacheable = "YES";
}
}
上面的 VCL 适用于 Varnish 3.0,它检查各种阻止内容被缓存的条件,返回hit_for_pass
不可缓存的项目,并X-Cacheable
相应地设置标头。