我有一个电子商务应用程序,我正在尝试通过Symfony2 Reverse Proxy进行缓存设置,但最终希望在生产环境中使用Varnish。我正在使用Apache2上的Symfony 2.1.8。
我的问题是,当主控制器动作被缓存时(对于像购物篮内容这样的私人内容非常重要),我无法重新检查每个请求的ESI标记,但我不明白为什么。
例如,我使用以下代码缓存主页:
渲染的模板继承基础布局模板,其中包含以下ESI以显示购物篮:
(编辑:在阅读Diego的答案后,我也使用了推荐的语法:
在首页以外的页面上(尚未被缓存的页面),购物篮摘要缓存运作良好,它总是显示正确的数据。只有当您返回主页时才会看到过时的信息。日志确认了除非实际呈现
编辑
在每个页面请求之后使用
这是针对缓存首页的内容:
我的问题是,当主控制器动作被缓存时(对于像购物篮内容这样的私人内容非常重要),我无法重新检查每个请求的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
);
}
}
在首页以外的页面上(尚未被缓存的页面),购物篮摘要缓存运作良好,它总是显示正确的数据。只有当您返回主页时才会看到过时的信息。日志确认了除非实际呈现
indexAction
,否则 summaryAction
不会在主页上调用。编辑
在每个页面请求之后使用
error_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 应该用于的事情。