Caching 使用Symfony2,为什么缓存响应中的ESI标记被忽略?

Caching 使用Symfony2,为什么缓存响应中的ESI标记被忽略?,caching,symfony,symfony-2.1,esi,Caching,Symfony,Symfony 2.1,Esi,我有一个电子商务应用程序,我正在尝试设置缓存-最初通过Symfony2反向代理,但最终通过生产中的Varnish。我正在Apache2上使用Symfony 2.1.8 我的问题是,当缓存主控制器操作时,我无法为每个请求重新检查ESI标记(对于篮子内容等私有内容很重要),但我不明白为什么 例如,我使用以下代码缓存主页: public function indexAction(Request $request) { // check cache $homepage = $this-&

我有一个电子商务应用程序,我正在尝试设置缓存-最初通过Symfony2反向代理,但最终通过生产中的Varnish。我正在Apache2上使用Symfony 2.1.8

我的问题是,当缓存主控制器操作时,我无法为每个请求重新检查ESI标记(对于篮子内容等私有内容很重要),但我不明白为什么

例如,我使用以下代码缓存主页:

public function indexAction(Request $request)
{
    // check cache
    $homepage = $this->getHomepage();

    $response = new Response();
    $response->setPublic();
    $etag = md5('homepage'.$homepage->getUpdated()->getTimestamp());
    $response->setETag($etag);
    $response->setLastModified($homepage->getUpdated());

    if ($response->isNotModified($request))
    {
        // use cached version
        return $response;
    }
    else
    {
        return $this->render(
            'StoreBundle:Store:index.html.twig',
            array(
                'page' => $homepage
            ),
            $response
        );
    }
}
渲染模板扩展了基本布局模板,其中包括以下ESI以显示篮:

{% render 'PurchaseBundle:Basket:summary' with {}, { 'standalone': true } %}
(编辑:在阅读Diego的答案后,我还使用了推荐的语法:

{% render url('basket_summary') with {}, {'standalone': true} %}
不幸的是,这并没有产生任何影响。)

我一直在玩篮子摘要的代码,但这是我目前拥有的

public function summaryAction()
{
    $response = new Response();
    $response->setPrivate();
    $response->setVary(array('Accept-Encoding', 'Cookie'));

    if ($this->basket->getId())
    {
        $etag = md5($this->getUniqueEtag());
        $response->setLastModified($this->basket->getUpdated());
    }
    else
    {
        $etag = md5('basket_summary_empty');
    }

    $response->setETag($etag);

    if ($response->isNotModified($this->request))
    {
        // use cached version
        return $response;
    }
    else
    {
        return $this->render(
            'PurchaseBundle:Basket:summary.html.twig',
            array(
                'basket' => $this->basket
            ),
            $response
        );
    }
}
在除主页(尚未缓存)之外的页面上,篮子摘要缓存工作正常,它始终显示正确的数据。只有当你回到主页时,你才会看到过时的信息。日志记录确认主页上不会调用
summaryAction
,除非
indexAction
实际呈现

编辑 在每次页面请求之后,使用
error\u log($kernel->getLog())
我为一个非缓存页面获得以下信息:

GET /categories/collections: miss; GET /_internal/secure/PurchaseBundle:Basket:summary/none.html: stale, valid, store; GET /_internal/secure/CatalogBundle:Search:form/none.html: miss; GET /esi/menu/main: fresh
对于缓存的主页:

GET /: fresh

我肯定遗漏了一些明显的东西,但文档似乎没有涵盖这一点,但它暗示这正是ESI应该用来做的事情。

因为2.0.20/2.1.5 Symfony2采用完全限定的URL,而不是控制器逻辑路径,如所示。因此,与您当前的ESI不同:

{% render 'PurchaseBundle:Basket:summary' with {}, { 'standalone': true } %}
您应该创建路由,然后在细枝上使用url方法:

{% render url('basket_summary') with {}, {'standalone': true} %}
还要注意的是,今天(3月1日)Symfony的新稳定版本(2.2.0)已经发布。在这个新版本中,您可以采取两种方法(摘自本书HTTP缓存一章的内容):


当前版本的链接章节的旁注也值得一读,因为它们包含了一些有用的信息和提示,可以帮助您找到实际问题。

Symfony2中的ESI似乎不适用于您使用的Latmodified/Etag缓存验证结构。请看这里:

类似问题如下:


我一直在尝试做与您相同的事情,但只能通过使用过期缓存使ESI正常工作。

谢谢您提供的附加信息-我相信我会在某个时候升级到2.2。我看到了CVE记录,但认为它意味着我也可以使用该表格。我已经检查并切换了url(“路由”)的逻辑路径,清除了缓存,但仍然存在相同的问题。感谢您的回复,您在2.2上试用过吗?我很快就会回来,所以我会回来报告,希望所有的子请求更改都会有松动。我的测试是在2.0.23中进行的,不确定2.2。祝你好运!
{# you can use a controller reference #}
{{ render_esi(controller('...:news', { 'max': 5 })) }}

{# ... or a URL #}
{{ render_esi(url('latest_news', { 'max': 5 })) }}