我在项目中使用了esi和Varnish作为缓存代理服务器。主代码块的ttl为1小时,几个代码块的ttl为10分钟。是否可以像下面描述的那样在主esi标签中加入esi标签?
main.html.twig
<esi:include src="/?action=menu/topBar"/>
<esi:remove>
{% include('partials/header/topBar.html.twig') %}
</esi:remove>
顶栏.html.twig
<esi:include src="/?action=index/extraLink" />
<esi:remove>
{% include('partials/header/extraLink.html.twig') %}
</esi:remove>
绝对可以递归处理ESI。这只是你的VCL如何配置的问题。
我看到你用Twig来渲染ESI标签。我假设你使用Symfony框架来处理这些Twig模板。如果是这样的话,解决方案很简单。
请看一下 https:/symfony.comdoccurrenthttp_cacheesi.html。 第一。
Symfony有一个 render
Twig的函数,它将控制器路由作为一个内部子请求来处理,并直接返回HTML。这是您的 {% include %}
呼叫。
但是很酷的是,Symfony也有一个叫做 render_esi
函数。这将采用一个控制器路径,并自动将其输出为一个 ESI标签 附带 src
属性。
Symfony会验证它是否位于支持ESI的Varnish服务器后面。它使用一个握手的过程来完成。如果ESI验证没有成功,它将回到典型的 render
行为,而只是将HTML作为一个内部子请求返回。
这个行为和你的Twig脚本是一样的,在Twig脚本中你同时使用了
<exi:include />
和<esi:remove />
作为后备力量。该render_esi
函数以一种更有效的方式处理这个问题。如果你的Symfony安装不支持
render_esi
功能,请安装以下Composer包。https:/packagist.orgpackagessymfonytwig-bridge。
为了确保Symfony能够进行正确的验证,在幕后发生了以下事情。
Surrogate-Capability
标头来宣布它提供ESI支持Surrogate-Control
标头,向Varnish表明它也可以处理ESI。下面是这些头文件的一个例子。
Surrogate-Capability: abc=ESI/1.0
Surrogate-Control: content="ESI/1.0"
如上所述 https:/symfony.comdoccurrenthttp_cachevarnish.html。你可以使用下面的VCL片段来处理VCL。
sub vcl_recv {
// Add a Surrogate-Capability header to announce ESI support.
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_backend_response {
// Check for ESI acknowledgement and remove Surrogate-Control header
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
你需要的Twig语法如下。
main.html.twig:
{% render_esi("/?action=menu/topBar") %}
topBar.html.twig。
{% render_esi("/?action=index/extraLink") %}
参见 https:/symfony.comdoccurrentreferencetwig_reference.html#render-esi。 更多关于 render_esi
.