我在设置 Varnish 以正确处理包含 ESI 的子请求的会话 cookie 时遇到问题。
背景,SSCCE
三个文件:index.php
,navigation.php
并footer.php
使用 ESI 组合在一起,其中前两个文件是有状态的,但只是index.php
可缓存的,而footer.php
完全是无状态的。
### index.php
<?php
session_start();
header('Cache-Control: public, s-maxage=10');
header('Surrogate-Control: content="ESI/1.0"');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Varnish test</title>
</head>
<body>
<esi:include src="http://localhost/WWW/navigation.php" />
<p>Primary content: <?php echo date('r') ?></p>
<esi:include src="http://localhost/WWW/footer.php" />
</body>
</html>
### footer.php
<?php
header('Cache-Control: public, s-maxage=20');
?>
<p>Footer: <?php echo date('r') ?></p>
### navigation.php
<?php
session_start();
if (!isset($_SESSION['counter'])) {
$_SESSION['counter'] = 0;
}
$_SESSION['counter'] += 1;
header('Cache-Control: private');
?>
<p>Navigation: <?php echo $_SESSION['counter'] ?></p>
清漆 VCL 配置:
sub vcl_recv {
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_fetch {
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
期望的结果
我希望看到index.php
/footer.php
从缓存中加载,每 10/20 秒清除一次,同时navigation.php
直接从后端服务器加载。当然,必须设置第一个index.php
不能作为标头缓存的请求,但是可以从一开始就从缓存中加载。Set-Cookie
footer.php
我怎么能做到这一点?我知道Cookie
HTTP 请求中存在标头会导致缓存未命中,但我不能简单地删除它。