【问题标题】:Building highly scalable web services构建高度可扩展的 Web 服务
【发布时间】:2011-02-03 18:23:23
【问题描述】:

我和我的团队正在开发一个需要能够处理大量流量的应用程序。不是 facebook 级别,但将来我希望能够扩展到该级别,而无需重写大量代码。

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

这是一个好方法吗?

【问题讨论】:

标签: php web-services scalability


【解决方案1】:

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

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

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

  • 使用PHP e-Accelerator等工具缓存编译后的脚本;应该有助于提高 Web 层的性能

High Scalability 上也有一些很棒的文章,您可能会觉得有帮助。

最后,请记住,过度设计解决方案很容易。最好的办法是在此过程中持续测量负载、性能、资源利用率等 - 然后根据需要使用这些数据进行调整。

【讨论】:

    【解决方案2】:

    缓存、缓存和更多缓存。 SQL查询缓存,操作码缓存,避免对同一事物多次查询。然后在你跑步时使用分析器来跟踪你的慢点在哪里。

    【讨论】:

    • 我同意,缓存很棒,因为它可以使 99.99% 的点击交付静态内容,而不是编译每个请求。但这更多是在优化方面,而不是真正的缩放。
    【解决方案3】:

    模块化

    我的想法是模块化 一切都变成单独的服务 他们自己的接口。所以例如 消息传递将有消息传递 接口可能有发送和 getMessages() 作为方法,然后 PHP web 应用程序会简单地查询这个 通过肥皂或卷曲界面或 类似的东西

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

    一些快速提示:

    我和我的团队正处于中间 开发需要的应用程序 能够处理相当重的 交通。不是facebook级别,而是在 未来我希望能够 无需大量代码即可扩展至此 重写。

    • 像其他人也暗示我建议你看看High Scalability blog
    • 首先使用YSlow / google page speed关注前端。这种优化很容易实现,可以给你带来显着的提升。来自 Yslow 网页的引述:

    80% 的最终用户响应时间是 花费在前端。这大部分 时间都花在了下载所有 页面中的组件:图像, 样式表、脚本、Flash 等。 减少组件的数量 反过来减少HTTP的数量 呈现页面所需的请求。 这是加快页面速度的关键。

    • 我还建议您查看HipHop for php,它将您的 php 代码转换为 C 代码,这对 facebook 来说是一个巨大的推动力。引用文章:

    使用 HipHop,我们减少了 CPU 我们的 Web 服务器上的平均使用量为 大约百分之五十,取决于 页。更少的 CPU 意味着更少的服务器, 这意味着更少的开销

    • 如果还没有设置的话,我猜另一个大/简单的改进是使用 APC(操作码缓存)来缓存您的编译代码。这会给你带来巨大的提升(对于转换为 HipHop 的部分来说不是必需的)。
    • 如果您希望您的网站规模扩大,您必须遵循以下原则:

      RAM is the new Disk

      !缓存,缓存,缓存! 例如 APC、memcachedredis

    • 首先分析您的 PHP 代码,然后优化容易实现的目标。我发现这个来自 Rasmus Lerdorf 的 audio 文件非常有用。阅读博文时,您会发现很多提高性能的好技巧。
    • 另外,我会考虑放弃关系数据库,转而使用 Cassandra。这是我最近看到很多大玩家做的一个动作(例如 twitter、digg、facebook、reddit)。你必须以一种完全不同的心态走这种方式,但我敢打赌,这完全值得付出努力。
    • Queue everything and delight every one 与例如beanstalkdgearman 或谷歌应用引擎的taskqueue

    【讨论】:

      【解决方案4】:

      然而,围绕一组模块进行高级设计是管理复杂性和结构开发的好方法(在微观层面更是如此)

      PHP Web 应用程序只需通过soap 或curl 查询此接口

      这会在应用程序中引入大量延迟。我建议定义 API,但对于任何同步处理的请求,请在单个线程中运行尽可能多的代码。

      当然,如果您必须处理多种开发语言,使用在 HTTP 上运行的接口是一个非常实用的解决方案 - 但如果您使用 PHP 开发前端,那么通过编程到抽象的 PHP API(可能调用Soap、Corba 或其他东西),您仍然可以选择稍后以不同的方式重新实现后端。

      我不确定您所说的消息传递是什么意思。如果您正在谈论异步请求处理,那么您需要考虑如何在 PHP 中实现订阅者。这是一个完整的蠕虫罐头——我还没有看到一个用 PHP 编写的好的消息处理系统——但我也没有看到一个用 Java 编写的好的可扩展解决方案——其中包括一些主要高端玩家推出的产品系统。也许有一天我会写一个;)与此同时,您真的希望让您的复杂(并且可能不太可靠)的业务逻辑与任何类型的订阅者守护进程在单独的线程中运行 - 所以一个明显的方法是将目标公开为网页,让订阅者作为守护进程运行,该守护进程简单地获取消息并调用基于 Web 的 API。

      如果您完全关心性能/可靠性/可扩展性,您真的不想围绕消息传递建立一个同步系统。

      HTH

      C.

      【讨论】:

        猜你喜欢
        • 2011-05-06
        • 2013-07-25
        • 2012-09-10
        • 1970-01-01
        • 2014-07-03
        • 2013-06-26
        • 1970-01-01
        • 1970-01-01
        • 2016-09-20
        相关资源
        最近更新 更多