我使用 Varnish 进行缓存。我创建了一个 ESI 组件并在我的代码中使用它
<esi:include src="/esi/my-component" />
它工作得很好,除了一件事。它不在缓存中。在后端,我设置响应标头
header('Content-Type: text/html');
header('Vary: Accept-Encoding');
header('Cache-Control: public, max-age=300, stale-while-revalidate=600, stale-if-error=600');
header('Surrogate-Control: max-age=300, stale-while-revalidate=600, stale-if-error=600');
header('Pragma: cache');
我看到缓存在我发出curl请求时起作用(我有HIT响应),但是当我更改响应内容时,我的浏览器立即获取它,这意味着缓存不适用于浏览器。 我有一个理论认为这是因为 cookie - 所以我应该在 esi 请求的清漆配置中删除它吗?有没有办法在不取消cookie的情况下实现缓存?
饼干在这个故事中确实扮演了重要角色。
如内置 VCL 中所述,如果 Varnish 在请求中看到
Cookie
或 Authorization
标头,则不会缓存。
这是您需要在 VCL 中缓解的问题,就像针对顶级请求执行此操作一样:
即使您删除了跟踪 cookie,仍然可能会留下一些 cookie,例如会话 cookie。由您决定您的 ESI 组件是否依赖 cookie 值。
如果您不需要 cookie,您可以在 VCL 中执行以下操作,仅针对 ESI 组件删除它们:
sub vcl_recv {
if(req.url ~ "^/esi/component") {
unset req.http.Cookie;
}
}
这将确保从
/esi/component
的请求中剥离 cookie,使请求可缓存,同时为可能需要它们的其他请求保留 cookie。
虽然我们暗示 cookie 是导致缓存未命中的原因,但只有一种方法可以真正找出答案:使用
varnishlog
调试请求。
您可以运行以下命令来检查
/esi/component
的请求:
sudo varnishlog -g request -q "ReqUrl ~ '^/esi/component'"
不要犹豫,将日志输出作为预格式化文本附加到您的原始问题中。我可以帮你调试。
我还想参考故障排除教程的以下部分,它可以帮助您找出 Varnish 未从缓存中提供特定项目的原因。