fes*_*sja 20 caching varnish symfony esi
在一个拥有大量流量的新项目中,我们正在思考如何构建我们的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)
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
HTML将缓存在网关(Symfony或Varnish)上.地点列表也将在网关上大部分时间缓存.用户数据请求将是被调用但不被缓存的用户数据(至少最初不是).
问题:
非常感谢!
我们在一个站点上使用Varnish进行整页缓存,并且我已经使用Symfony2几年了,但请记住,我没有在任何生产环境中使用Varnish + Symfony2 + ESI.
我认为基本的想法是可以的.如果许多页面中的菜单相同,并且许多页面上的位置列表也相同,则会获得Varnish或Symfony反向缓存缓存的常用内容.由于Varnish通常在内存中保存缓存,因此您可以更快地获得内容,而无需在每次请求时调用呈现和数据库查询代码.
如果用户已登录,那么困难的部分就是使那些ESI请求被缓存.据我所知,在默认的Varnish配置中,其中包含Cookie的请求永远不会被缓存.如果您倾向于将cookie传递给ESI请求,则不会在用户之间共享这些ESI响应.
您可以尝试从URL制定一些规则,但如果您使用默认的Symfony twig帮助程序,生成的URL是/ _internal/...,因此可能很难区分公共和私有.
您也可以配置为Cache-Control: public
在传递时始终忽略任何cookie .默认情况下,这在Symfony中完成:
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
$response->setPrivate(true);
}
Run Code Online (Sandbox Code Playgroud)
正如您从代码中看到的那样,如果您有public
指令,则响应永远不会是私有的.
我还没有找到Varnish如何处理这个指令 - 据我所知,它没有默认缓存任何有cookie的请求.所以我认为你必须调整配置才能实现这一目标.
如果还要缓存主页面,我看不到你如何跳过包含.
我认为你的注册用户(不是搜索机器人)需要JS,所以我建议使用Javascript来区分用户数据的加载.
如果用户有cookie session-id
等,则可以查看Javascript代码,并仅在此情况下请求获取数据.设置其他cookie可能也是一个好主意,比如_loggedin
避免Javascript代码获取会话ID.
未登录的用户也可以在cookie中包含一些数据,例如_likedPost:1,2,132
.Javascript可以获取此cookie并进行一些HTML更正,甚至不需要额外的请求.
正如我们对这些cookie所做的那样:我们将仅限JS的cookie与应用程序cookie分开.我们通过一些模式来做到这一点,比如_\w
JS cookies.然后我们调整了Varnish配置以拆分Cookie标头并删除这些仅限JS的cookie.然后,如果没有其他cookie,则与每个人共享响应.应用程序(Symfony)不会获取这些cookie,因为它们被剥离.
我认为如果在每个页面中它都是相同的话.
我认为ESI很好,因为Varnish可以在内存中保存缓存.因此,它可能甚至不会对您的硬盘进行任何查询.由于您的控制器缓存可能也在内存中,我认为Varnish会比Symfony框架更快地查找缓存,包括所有路由,PHP代码,服务初始化等.
这取决于,但我认为这可能是更好的方法.请记住,缓存过着不同的生活.例如,如果您的地点列表缓存了2个小时,则在此时间结束时,地点可能已更改 - 某些新项目在列表中是新项目,其中一些项目缺失.您的用户列表仍然是旧的(缓存),但您提供有关新列表的用户数据 - 不需要某些数据,其中一些数据丢失.
通过javascript获取加载位置可能是更好的方法,例如搜索某些HTML属性data-list-item-id
,然后发出ajax请求查询有关这些项的数据.在这种情况下,您的用户数据将与当前缓存列表同步,您可以为两个列表而不是2列表发出1 ajax请求.
如果未使用高速缓存失效(PURGE请求),则所有HTTP高速缓存都可以很好地扩展.您可以将应用程序扩展到多个服务器,并按照某种规则配置Varnish随机调用它们,或者只使用其中一个作为故障保护.如果带宽仍然太大,您可以随时修改缓存超时和其他配置.
归档时间: |
|
查看次数: |
2459 次 |
最近记录: |