ESI 组件的 Varnish 缓存

问题描述 投票:0回答:1

我使用 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的情况下实现缓存?

caching varnish varnish-vcl edge-side-includes
1个回答
0
投票

饼干在这个故事中确实扮演了重要角色。

内置 VCL 中所述,如果 Varnish 在请求中看到

Cookie
Authorization
标头,则不会缓存。

这是您需要在 VCL 中缓解的问题,就像针对顶级请求执行此操作一样:

  • 绕过不可缓存路由的缓存,并删除所有其他请求的 cookie
  • 或者有选择地删除 Cookie,仅保留应用程序中需要的 Cookie

剥离 ESI 组件的 cookie

即使您删除了跟踪 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 未从缓存中提供特定项目的原因。

© www.soinside.com 2019 - 2024. All rights reserved.