我已经设置了Varnish(端口80)来缓存来自Node.js服务器(端口8080)的请求,该服务器通常以一位数的毫秒响应(但有时会显着更长)。
我在PHP中设置了一个简单的基准测试(我知道'一次只能发送一个请求):
// Measure time for backend (bypassing Varnish by using port 8080)
$t = microtime(true);
foreach ($requests as $request){
file_get_contents($request["url"] . ":8080/?" . http_build_query($request["parameters"]));
}
$t = microtime(true) - $t;
echo "Backend: " . $t . "\n";
// Measure time for Varnish (using port 80 after Varnish restart)
$t = microtime(true);
foreach ($requests as $request){
file_get_contents($request["url"] . ":80/?" . http_build_query($request["parameters"]));
}
$t = microtime(true) - $t;
echo "Varnish MISS: " . $t . "\n";
// Measure time for Varnish (now cached)
$t = microtime(true);
foreach ($requests as $request){
file_get_contents($request["url"] . ":80/?" . http_build_query($request["parameters"]));
}
$t = microtime(true) - $t;
echo "Varnish HIT: " . $t . "\n";
// Results:
Backend: ~10 seconds
Varnish MISS: ~65 seconds
Varnish HIT: ~2 seconds
我测试~1400个请求。平均而言,Varnish会为每个错过的请求增加30-40毫秒的开销。
Varnish中缓存未命中的开销似乎非常大,我发现其他人报告了类似的结果 - 没有人能够解释为什么或如何减少开销。
所以我的问题是,为什么会有这么大的开销,我该如何减少呢?
我知道缓存的想法是避免优化初始请求的响应时间,但是这个特定的Web服务会在短时间内看到大量的唯一请求(但是很多重新请求超过了几天),所以Varnish的开销有点重要。
清漆设置
vcl 4.0;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
unset req.http.Cookie;
}
sub vcl_backend_response {
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
答案 0 :(得分:2)
在向Varnish人询问这个问题后,他们建议我尝试在同一台服务器上复制它,但后端不同。尝试使用Apache后端没有问题。
检查Varnish的响应越近我注意到,对于Node.js服务器,会有快速完成的请求的Content-Length标头(由Varnish设置),但不会放在那些缓慢完成的请求上。
向Node.js服务器响应添加Content-Length标头(默认情况下在Apache中添加)修复了该问题。