构建高度可扩展的网络服务。

12

我和团队正在开发一个需要处理相当大的流量的应用程序,虽然不是像Facebook那样庞大的流量,但未来我希望能够扩展到那个级别,而无需进行大规模的代码重写。

我的想法是将所有内容模块化为具有自己接口的单独服务。例如,消息传递应该有一个消息传递接口,其中可能具有发送和getMessage()等方法,然后PHP Web应用程序将通过soap或cURL等方式查询此接口。消息传递应用程序可以是任何类型的应用程序,因此适合特定功能的Java应用程序或Python等,具有自己的独立数据库分片。

这种方法好吗?


顺便说一下,这是一本价格优惠的好书:LORNA MITCHELL - PHP Web Services : http://shop.oreilly.com/product/0636920028291.do - Sliq
4个回答

20

模块化

我的想法是将所有内容模块化为独立的服务,并拥有自己的接口。例如,消息传递将具有一个消息传递接口,该接口可能具有send和getMessages()方法,然后PHP Web应用程序将通过soap或curl等方式查询此接口。

我喜欢将每个服务模块分开(良好的编码原则)。我不喜欢SOAP的部分 :(. 我认为它太复杂了。我会选择类似于JSON-RPC之类的东西。

一些快速提示:

我和我的团队正在开发一个需要处理相当大量流量的应用程序。虽然不是Facebook级别的,但在未来,我希望能够扩展到那个级别而不需要进行大规模的代码重写。

  • 就像其他人暗示的一样,我建议您查看High Scalability blog
  • 首先,使用YSlow / google page speed专注于前端。这种优化很容易实现,并且可以显著提升性能。来自Yslow网页的一句话:

80%的终端用户响应时间 花费在前端。大部分时间都花在下载页面上的所有内容:图像、样式表、脚本、Flash等。减少组件数量可以减少呈现页面所需的HTTP请求数量。这是更快页面的关键。

  • 我还建议您查看HipHop,用于将您的php代码转换为C代码,这对Facebook来说是一个巨大的提升。一篇文章的引语:

通过HipHop,我们成功将Web服务器上的CPU使用率平均降低了约50%,具体取决于页面。更少的CPU意味着更少的服务器,这意味着更少的开销。

  • 我猜如果你还没有设置,另一个大而简单的改进就是使用APC(opcode缓存)来缓存您编译过的代码。这将为您带来巨大的提升(对于转换为HipHop的部分来说不是必需的)。
  • 如果您想使您的网站具有可扩展性,您必须遵循以下口号:

    RAM是新的硬盘

    !缓存,缓存,缓存!例如使用APC、memcachedredis等。

  • 首先分析您的PHP代码,然后优化低效果的代码。我发现Rasmus Lerdorf的音频文件非常有用。阅读博客文章时,您会发现许多有关提高性能的好建议。
  • 此外,我会考虑放弃关系数据库,转而使用例如Cassandra的解决方案。最近我看到很多大公司都在采取这种方式(例如Twitter、Digg、Facebook、Reddit)。您将不得不以完全不同的思维方式进行操作,但我敢打赌,这将完全值得努力。
  • 将所有内容都排队,让每个人都感到愉悦,例如使用beanstalkdgearman或Google App Engine的taskqueue

5

作为第一步,这听起来是合理的,但请记住PHP层和消息传递层之间的流量会增加一些延迟。您还可以考虑以下几点:

  • 在PHP层缓存数据,使用(例如)memcached。您还可以考虑使用Web代理缓存,例如squid

  • 通过将会话数据存储在数据库中等方式,将Web服务器扩展到多台机器上。一旦您可以支持两个Web服务器,添加第三个(第四个、第五个等等)应该很简单。请记住,您最终可能需要将消息传递层扩展到多台机器。

  • 使用诸如PHP e-Accelerator之类的工具缓存已编译的脚本;这应该有助于提高Web层的性能

还有一些关于High Scalability的优秀文章,您可能会发现它们很有帮助。

最后,请记住过度设计解决方案很容易。您最好不断测量负载、性能、资源利用等方面的数据,然后根据需要进行调整。


1

缓存,缓存,再缓存。SQL查询缓存,opcode缓存,避免多次查询同一内容。然后在运行时使用分析器来跟踪您的慢点所在。


1
我同意,缓存非常棒,因为它可以使99.99%的请求提供静态内容而不是编译每个请求。但这更多是优化方面,而不是真正的扩展。 - Sliq

0
将高级设计围绕一组模块构建是管理复杂性和结构开发的好方法(尤其是在微观层面上),然而,PHP Web应用程序只需通过SOAP或CURL查询此接口。
这会给应用程序引入很多延迟。我建议定义API,但对于任何同步处理的请求,请尽可能在单个线程中运行尽可能多的代码。
当然,如果您必须处理多种开发语言,则使用在HTTP上运行的接口是非常实用的解决方案,但如果您正在使用PHP开发前端,则通过编程到抽象的PHP API(可能调用Soap、Corba或其他内容),您仍然可以稍后以不同的方式重新实现后端。

我不确定你所说的消息是什么意思。如果你在谈论异步请求处理,那么你需要考虑如何在PHP中实现一个订阅者。这是一个完整的问题 - 我没有看到过一个好的消息处理系统写在PHP中 - 但我也没有看到一个好的可扩展解决方案写在Java中 - 包括一些高端系统中的主要玩家推销的产品。也许有一天我会写一个 ;) 在此期间,你真的想把你复杂(可能不太可靠)的业务逻辑与任何类型的订阅守护程序分开运行 - 所以一个明显的方法是将目标公开为一个网页,并将订阅者作为一个守护进程运行,简单地接收消息并调用基于Web的API。

如果你关心性能/可靠性/可扩展性,你真的不想在消息传递周围建立同步系统。

希望对你有所帮助。

C.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接