在一个流量很大的新项目中,我们正在考虑如何构建我们的Symfony2应用程序,以利用缓存的优势,并为未来的更具侵略性做好准备。我很想知道你的意见。
假设用户请求一个页面,其中包含位置列表。此页面包含:
- list
- common data (title, author, description)
- user data (the user likes the list + other data)
- first 20 places
- common data (title, photo of each place)
- user data (the rates of the user for those places)
HTML可能如下所示:
<html>...
<body>
<header>
...
<!-- Embed the top user menu -->
<esi:include src="http://example.com/profile/menu" />
...
</header>
<content>
...
common data of the list
...
<!-- Embed the common data of the first 20 places, the same for everyone -->
<esi:include src="http://example.com/lists/17/places" />
...
<!-- Embed the user data of the list (used in JS) -->
<esi:include src="http://example.com/lists/17/user" />
...
<!-- Embed the user data of the list of places (used in JS) -->
<esi:include src="http://example.com/lists/17/places/user" />
...
</content>
</body>
</html>
HTML将被缓存到网关上(Symfony或Varnish)。位置列表大部分时间也会被缓存在网关上。用户数据请求将是那些被调用但未被缓存的请求(至少最初不会)。
问题
非常感谢!
发布于 2012-12-12 06:39:09
我们在一个站点上使用Varnish进行整个页面缓存,我使用Symfony2已经有几年了,但请记住,我还没有在任何生产环境中使用Varnish + Symfony2 + ESI。
,
困难的部分是,如果用户已登录,则缓存这些ESI请求。据我所知,在默认的Varnish配置中,包含Cookie的请求永远不会被缓存。如果您倾向于将cookies传递给ESI请求,则这些ESI响应将不会在用户之间共享。
您可以尝试从URL制定一些规则,但如果您使用默认的Symfony twig helper,则生成的URL是/_internal/...,因此可能很难区分公共URL和私有URL。
您还可以配置为在传递Cache-Control: public
时始终忽略任何cookies。这在Symfony中是默认完成的:
如果($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) { $response->setPrivate(true);}
正如您从代码中看到的,如果您有public
指令,响应将永远不会是私有的。
我还没有发现Varnish是如何处理这个指令的--据我所知,默认情况下,它不会缓存任何有cookie的请求。所以我认为你必须调整配置来实现这一点。
我假设你的注册用户(不是搜索机器人)需要JS,所以我建议使用Javascript来区别用户数据的加载。
在这种情况下,Javascript代码可以查看用户是否有cookie、session-id
等,并发出获取数据的请求。设置一些其他cookie也可能是一个好主意,比如_loggedin
,以避免Javascript代码获取会话id。
未登录的用户也可以在cookies中包含一些数据,如_likedPost:1,2,132
。Javascript可以获得这个cookie并进行一些HTML更正,甚至不需要发出额外的请求。
正如我们对这些cookie所做的那样:我们将仅用于JS的cookie与应用程序cookie分开。我们是通过某种模式做到这一点的,比如JS cookie的_\w
。然后,我们调整了Varnish配置,拆分Cookie头并删除这些仅限JS的Cookie。然后,如果没有其他cookie,则与每个人共享响应。应用程序(Symfony)不会得到这些cookie,因为它们被剥离了。
使用javascript获取已加载的位置可能是更好的方法,例如,搜索一些像data-list-item-id
这样的超文本标记语言属性,然后发出ajax请求来查询关于这些项目的数据。在这种情况下,您的用户数据将与当前缓存列表同步,您可以为这两个列表创建1个ajax请求,而不是2个。
https://stackoverflow.com/questions/13574775
复制相似问题