首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何构建一个具有扩展能力的Symfony2应用程序?

如何构建一个具有扩展能力的Symfony2应用程序?
EN

Stack Overflow用户
提问于 2012-11-27 07:11:28
回答 1查看 2.5K关注 0票数 20

在一个流量很大的新项目中,我们正在考虑如何构建我们的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)。位置列表大部分时间也会被缓存在网关上。用户数据请求将是那些被调用但未被缓存的请求(至少最初不会)。

问题

  1. 你觉得这种结构怎么样?
  2. 如果用户是匿名的,我可以避免对用户数据进行esi-includes吗?另外,如果我有一个匿名用户的cookie?
  3. 用户菜单的esi-include有意义吗?
  4. ,还是我们应该忘记ESI,总是遍历控制器(缓存
  5. 的公共数据渲染视图,我们将请求用户数据的两个ESI请求移动到AJAX调用,而不是在服务器上等待?
  6. 如果我们需要快速扩展,这是一个好方法吗?)什么是最好的?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-12 06:39:09

我们在一个站点上使用Varnish进行整个页面缓存,我使用Symfony2已经有几年了,但请记住,我还没有在任何生产环境中使用Varnish + Symfony2 + ESI。

  1. ,我认为基本的想法是可以的。如果菜单在许多页面上是相同的,位置列表在许多页面上也是相同的,那么您将获得由Varnish或Symfony反向缓存缓存的公共内容。由于Varnish通常将缓存保存在内存中,因此您可以更快地获取内容,而不必在每次请求时调用呈现和DB查询代码。

困难的部分是,如果用户已登录,则缓存这些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的请求。所以我认为你必须调整配置来实现这一点。

  • 如果主页也要缓存,我不明白你怎么能跳过includes。

我假设你的注册用户(不是搜索机器人)需要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,因为它们被剥离了。

  • 我认为如果它在每个页面中都是相同的,那么它就会得到。

  • 我认为ESI很好,因为Varnish可以在内存中保留缓存。因此,它可能甚至不会对您的硬盘进行任何内容查询。因为你的控制器缓存可能也在内存中,我认为Varnish会比Symfony框架更快地查找缓存,所有的路由,PHP代码,服务初始化等。

  • ,这取决于它,但我认为它可能是更好的方法。请记住,缓存过着不同的生活。例如,如果您的位置列表被缓存了2小时,那么在这段时间结束时,位置可能已经更改-列表中的一些新项目是新的,而其中一些项目则丢失了。您提供给用户的列表仍然是旧的列表(缓存),但您提供了有关新列表的用户数据-有些数据是不需要的,有些数据丢失了。

使用javascript获取已加载的位置可能是更好的方法,例如,搜索一些像data-list-item-id这样的超文本标记语言属性,然后发出ajax请求来查询关于这些项目的数据。在这种情况下,您的用户数据将与当前缓存列表同步,您可以为这两个列表创建1个ajax请求,而不是2个。

  • 如果不使用缓存无效(清除请求),则所有HTTP缓存方案确实可以很好地扩展。您可以将应用程序扩展到多个服务器,并根据某些规则将Varnish配置为随机调用它们,或者只是使用其中一台服务器作为故障保护。如果带宽仍然太大,您可以随时修改缓存超时和其他configuration.
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13574775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档