缩放聊天应用 – 短轮询与长轮询(AJAX,PHP)

我运行一个网站,用户可以通过浏览器相互聊天(想想Facebook聊天)。 处理现场互动的最佳方式是什么? (现在我每30秒钟进行一次民意调查,以更新在线用户和新的传入消息,而另一项民意调查则每隔一秒在聊天页面上获取新消息。)

我考虑过的事情:

  • HTML5networking套接字:没有使用它,因为它不适用于所有的浏览器(只有铬)。
  • Flash套接字:没有使用这个,因为我想最终支持移动networking。

现在,我正在使用短轮询,因为我不知道如何可伸缩的AJAX长轮询。 我现在从servint运行VPS服务器(运行Apache)。 我应该使用长轮询还是短轮询? 我不需要绝对即时的响应时间(只是对于一个聊天应用程序“足够好”)。 有几十万用户会经常杀这个服务器吗? 我如何扩展这个,请帮助!

一些注意事项:

  • 每秒轮询是矫枉过正的。 检查之间的延迟几秒钟,应用程序仍然感觉非常敏感。
  • 要保存数据库的stream量和速度响应,请考虑使用内存caching来存储未传送的消息。 您仍然可以将消息保存到数据库,内存caching将仅用于查询新消息,以避免每个用户每隔x秒查询一次数据库。
  • 超时闲置x秒后,用户的聊天停止轮询到您的服务器。 这保证有人离开窗户不会继续产生stream量。 提供一个简单的“仍然存在?继续聊天”。 链接会话超时并在超时前警告用户,以便延长超时时间。
  • 我build议从轮询开始,而不是彗星/长轮询/sockets。 民意调查很容易build立和支持,短期内可能会收缩。 如果你得到很多的stream量,你可以扔硬件和负载平衡器的问题来扩展。 整个networking基于投票 – 投票最肯定的尺度。 有一点像慧星/长轮询等替代scheme的复杂性是有道理的,但是在额外的开发时间/复杂性是合理的之前,您需要大量的stream量。

在引入cometd和nodejs之前,这是每个人都曾经做过的事情。

我看到的问题是Apache上的PHP请求非常昂贵。 如果您的聊天应用程序每秒都会检查消息,则会发现自己处于Apache没有足够资源来响应请求的情况。 我认为需要改进的其他领域是改进聊天应用程序的上下文。

为什么它每秒更新,如果不检索新的消息? 如果没有消息呢?

你可以使用一些技巧;

  • 为您的客户端提供一个轻量级的端点,这些端点具有聊天会话的一些上下文,是一个新的待处理消息,多less条消息等等。如果没有新消息,客户端可以通过立即更新来响应此消息。 这个端点可以通过http请求提供一个简单的json对象。 你保证这个状态信息将是一个固定的大小,如果状态的响应没有改变,你可以衰减它。 看下一条消息。

  • 如果客户端连续几次从服务器接收到相同的响应,您可以在设定的时间内增加轮询,目前您说这是每秒一次。 如果你这样做,你会增加到每2,4,6,8,10秒。 一旦来自服务器的响应改变,你重置衰减。

一些优化要考虑;

  • 使用像APC一样的PHP操作码caching。

  • 设置所有请求的低超时,你不希望任何请求挂起你的服务器。

  • 优化您的PHP代码,使其精益和快速。

  • 运行一些负载testing,看看你的限制是什么。

  • 基准性能经常确保您的应用程序变得更快。

  • 检查Apache日志,告诉应用程序的整体健康状况和响应时间。

当需要扩展时,添加新的服务器并使用负载平衡器来分配请求。 我用Varnish和HAProxy取得了很大的成功,设置起来也不复杂。

如果我是你,我会select使用html5networking套接字的图书馆,但如果html5不可用的话,如果没有可用的Flashsockets,浏览器应该是分钟。

你也应该放弃php或用线程套接字服务器来补充它,或者用python或者ruby用em-websocket编写。