Symfony2:私有ESI片段

时间:2013-07-29 14:14:41

标签: caching symfony reverse-proxy esi

我想知道是否存在类似私有ESI片段的东西。在the docs我读到了:

  1. “设置共享的最大年龄 - ,这也将响应标记为公开
  2. “一旦开始使用ESI,请记住始终使用s-maxage 指令而不是max-age。因为浏览器只接收聚合资源,所以它不知道子组件,所以它将服从max-age指令并缓存整个页面。你不希望这样。“
  3. 我不完全了解我是否或无法按用户缓存页面的某些部分。有人可以解释一下吗?

    提前致谢!

2 个答案:

答案 0 :(得分:5)

您可以基于每个用户缓存部分页面。

他们的关键是清漆配置,你为ttl设置正常的共享最大年龄,和 然后将为该用户缓存esi请求。

然后看看这个Varnish cookbook caching for logged in users密钥 是您需要一个带有哈希用户ID的唯一cookie,并将示例中的myapp_unique_user_id替换为您的cookie名称。

这是一个示例控制器,其中包含缓存和非缓存操作。

<?php

namespace MyTest\Bundle\HomepageBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;

class TestController extends Controller
{
    /**
     * UnCached html content
     *
     * @Route("/test_cache", name="homepage")
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function homepageAction()
    {
        return $this->render('MyTestHomepageBundle::index.html.twig');
    }

    /**
     * Cached user specific content
     *
     * @param integer $myTestUserId
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @Route("/test_user_cached/{myTestUserId}", name="homepage_user_specific_content")
     */
    public function userSpecificContentAction($myTestUserId)
    {
        $response = $this->render('MyTestHomepageBundle::userSpecificContent.html.twig', array('userId' => $myTestUserId));
        $response->setPublic();
        $response->setSharedMaxAge(3600);

        return $response;
    }
}

这是你的index.html

<!DOCTYPE html>
<head></head>
<body>

<h1>My Test homepage - {{ "now"|date("F jS \\a\\t g:i:s") }}</h1>
{{ render_esi(url('homepage_user_specific_content')) }}
</body>

和userSpecificContent.html.twig

UserId: {{ userId }}  - {{ "now"|date("F jS \\a\\t g:i:s") }}

答案 1 :(得分:0)

只要您的ESI片段响应标头指示它不可缓存,varnish就不会缓存它。这是一个典型的用例 - 使用esi指令缓存父页面而不缓存包含的esi包含。那些文档在包含ESI的父页面上告诉你,使用s-maxage,这样浏览器就不会考虑页面可缓存,只有清漆。根据我的经验,您还应该从包含esi标记的响应中删除etag和最后修改的标题,因为它们不会响应包含esi的片段内容中的更改。

如果你不想在后端执行此操作,可以在vcl_fetch(不是linted)中执行此操作:

if (beresp.ttl > 0 && beresp.do_esi) {
   set beresp.http.Cache-Control = "s-maxage=" beresp.ttl; 
   unset beresp.http.etag;
   unset beresp.http.last-modified;
   /* Optionally */
   unset beresp.http.expires;
}