扩展聊天应用程序 - 短轮询与长轮询(AJAX、PHP)
Posted
技术标签:
【中文标题】扩展聊天应用程序 - 短轮询与长轮询(AJAX、PHP)【英文标题】:Scaling a chat app - short polling vs. long polling (AJAX, PHP) 【发布时间】:2011-07-15 21:06:17 【问题描述】:我经营一个网站,用户可以通过浏览器互相聊天(想想 Facebook 聊天)。处理实时交互的最佳方式是什么? (现在,我每 30 秒进行一次民意调查,以更新在线用户和新收到的消息,并且每秒在聊天页面上进行另一次民意调查以获取新消息。)
我考虑过的事情:
html5 Web Sockets:没有使用它,因为它不适用于所有浏览器(仅限 chrome)。 Flash Sockets:没有使用它,因为我想最终支持移动网络。现在,我正在使用短轮询,因为我不知道 AJAX 长轮询的可扩展性如何。我现在正在从 servint 运行 VPS 服务器(运行 apache)。我应该使用长轮询还是短轮询?我不需要绝对即时的响应时间(对于聊天应用程序来说“足够好”)。是否经常有几十万用户要杀死我的服务器的短轮询?我如何扩展这个,请帮助!
【问题讨论】:
我知道 Apache 通常不能很好地处理许多同时连接。并且还意识到可能有其他解决方案为此场景构建(nodejs 等)。但现在,我想避免重写整个应用程序。 针对不同平台实施多种解决方案怎么样?即,如果支持HTML5,浏览器使用HTML5,如果支持flash,浏览器使用flash,如果以上都不支持,浏览器使用ajax。 你可能对这个帖子感兴趣urbanairship.com/blog/2010/09/29/linux-kernel-tuning-for-c500k 【参考方案1】:几点说明:
每秒轮询是多余的。该应用程序仍然会感觉非常灵敏,检查之间会有几秒钟的延迟。 要保存数据库的流量和加快响应速度,请考虑使用内存缓存来存储未传递的消息。您仍然可以将消息持久化到数据库,内存缓存将仅用于查询新消息,以避免每个用户每隔 x 秒查询一次数据库。 在 x 秒不活动后使用户的聊天超时,以停止轮询您的服务器。这可以确保打开窗口的人不会继续产生流量。提供一个简单的“还在吗?继续聊天”。超时会话的链接,并在超时前警告用户,以便他们延长超时时间。 我建议从轮询开始,而不是彗星/长轮询/套接字。投票很容易构建和支持,并且在短期内可能会很好地扩展。如果您获得大量流量,您可以将硬件和负载均衡器放在问题上以进行扩展。整个网络都是基于投票的——投票肯定是规模化的。彗星/长轮询/等替代方案的复杂性在某种程度上是有意义的,但在证明额外的开发时间/复杂性合理之前,您需要大量流量。【讨论】:
您的最后一点非常有帮助 - 我一直在尝试确定我的应用程序中的第一个轮询实现需要如何面向未来,我想我会采纳您的建议并进行简单的轮询快速工作,然后计划一个明智的长期解决方案。【参考方案2】:如果我是你,我会选择一个使用 html5 网络套接字的库,但如果 html5 不可用,我会选择使用 Flash 套接字,那么被破解的浏览器应该是分钟级的。
此外,您应该放弃 php 或使用用 python 或 ruby 编写的带有 em-websocket 的线程套接字服务器来补充它。
【讨论】:
【参考方案3】:这是在引入 cometd 和 nodejs 之前每个人都做过的事情。
我看到的问题是 Apache 上的 PHP 请求非常昂贵。如果您的聊天应用程序每秒检查一次消息,您会发现自己处于 Apache 没有足够资源来响应请求的情况。我认为需要改进的另一个领域是改进聊天应用程序的上下文。
如果不是为了检索新消息,为什么它会每秒更新一次? 如果没有消息怎么办?
你可以使用的一些技巧;
为您的客户端提供一个轻量级端点,该端点具有一些关于聊天会话的上下文、一条新消息待处理、多少条消息等。如果没有,客户端可以通过立即更新或不更新来对此做出响应新消息。这个端点可以通过 http 请求提供一个简单的 json 对象。您可以保证此状态消息的大小是固定的,如果状态的响应没有改变,您可以衰减它。请参阅下一条消息。
您的 javascript 轮询中的一个简单衰减,如果客户端连续几次从服务器接收到相同的响应,您可以将轮询增加一个设定的时间,目前您说它是每秒一次。如果你这样做了,你会增加到每 2、4、6、8、10 秒。一旦服务器的响应发生变化,您就会重置衰减。
需要考虑的一些优化;
使用像 APC 这样的 PHP 操作码缓存。
为所有请求设置低超时,您不希望任何请求挂起您的服务器。
优化您的 PHP 代码,使其精简而快速。
运行一些负载测试以查看您的限制。
经常对性能进行基准测试,以确保您的应用程序变得更快。
检查 apache 日志,了解应用程序整体运行状况和响应时间的迹象。
当需要扩展时,添加新服务器并使用负载平衡器来分发请求。我使用 Varnish 和 HAProxy 取得了巨大成功,设置它们也并不复杂。
【讨论】:
动态增量是我从来没想过的,好点以上是关于扩展聊天应用程序 - 短轮询与长轮询(AJAX、PHP)的主要内容,如果未能解决你的问题,请参考以下文章