AJAX/PHP为什么HTTP轮询如此滞后



为什么HTTP轮询如此滞后?

我有一个按钮,每当用户单击它时,MySQL数据库字段就会更新,并向用户显示值。我每800毫秒轮询一次,它非常滞后/出现故障。有时,当点击按钮时,它不会注册它。实际上,我需要比每800毫秒更频繁地进行轮询。

这也是一次只有一个用户在网站上。。。当最后会同时出现很多的时候。

HTTP流/长轮询/Websockets而不是轮询

当您需要实时信息时,应避免(频繁)轮询。下面我将试图解释为什么这是错误的。你可以把它比作一个坐在你车后面的孩子,当你一直回答"我们还没有到"时,他每秒钟都在尖叫"我们还到吗"。

相反,您希望拥有长轮询/HTTP流或websocket之类的东西。你可以把这比作你车后面的一个孩子告诉你什么时候"我们在那里",而不是每秒钟都问我们。你可以想象这比前面的例子更有效率。

老实说,我认为PHP还不是这类应用程序的合适工具。您可以使用以下选项:

托管解决方案:

  • http://pusherapp.com:

    Pusher是一个托管的API,轻松安全地添加可扩展通过WebSockets实现实时功能网络和移动应用程序。


    我们的免费沙盒计划包括20个连接和100000条消息每天。只需升级到付费计划当你准备好了。

  • http://beaconpush.com/

    Beacon推送是使用创建实时web应用程序HTML5 WebSockets和Comet。

自己主持:

  • http://socket.io:

    Socket.IO旨在制作实时应用程序适用于所有浏览器和手机设备,模糊差异在不同的运输工具之间机制

当变得非常大时,"自己主机"解决方案会变得更便宜,但另一方面,使用类似pusherapp的解决方案会让你更容易开始(友好的API),而且也不会那么昂贵。例如,pusherapp的"Bootstrap"可以有100个并发连接,每天20万条消息,每月19美元(但当小型beaconpush更便宜时=>计算一下:)。附带说明的是,此计划不包括SSL,因此不能用于敏感数据。我想拥有一台专用机器(VPS)将花费你大约相同的钱(对于一个简单的网站),你还必须自己管理流媒体解决方案,但当它变得更大时,可能会更有吸引力。


内存而非光盘

每当用户单击MySQL时数据库字段得到更新值显示给用户

将磁盘I/O(标准模式下的MySQL)与内存进行比较时,速度非常慢。您应该使用内存中的数据库,例如redis(也有持久快照)或memcached(完全在内存中)来加快进程。我自己也非常喜欢redis,因为它速度快、简单、持久。http://redistogo.com/提供5MB内存的免费计划,可能会满足您的需求。如果不是这样,每月5美元的迷你计划可能会覆盖你,但当VPS变得更大时,它会更便宜,在我看来,这是首选的解决方案。


最佳解决方案

最好的解决方案(尤其是当你变得越来越大的时候)是使用VPS(成本高昂)来托管socket.io/redis。如果真的很小,我会用redistogo,如果不是,我会自己主持。我也会开始使用beaconpush/pusherapp之类的东西,因为它很简单(立即开始)。托管socket.io(建议在自己的机器上玩,以备变大时使用)非常简单,但在我看来比beaconpush/pusherapp更难。

滞后/故障?听起来像是客户端的问题。按钮的事情也是如此。我会先把你的JavaScript整理好。

至于轮询,0.8听起来有点时间紧迫。我不知道大多数国家的情况,但在第三世界,简单的网络数据包可能会延迟几秒钟。(更不用说连接中断、数据包丢失和光速了。)你的应用程序准备好应对这些了吗?

至于另一种方法,我同意@Vern的观点,即中断驱动的会更好。用HTTP术语来说,它转换为一个长期存在的HTTP请求,直到服务器有一些实际数据要发送,才会收到响应,从而最大限度地减少延迟和带宽。(AFAIK)这是一种比AJAX更古老的技术,尽管最近才被命名。搜索"COMET",您将同时得到客户端和服务器端库。

有很多事情可能会导致您所经历的滞后。您的服务器可能能够足够快地处理请求,但如果客户端和服务器之间的连接很慢,那么您将看到明显的滞后。

你应该尝试的第一件事是ping服务器,看看你得到的响应时间。

其次,您可能需要考虑一种中断驱动的方法,而不是轮询。这意味着只有当你的服务器回复时,你才会发出下一个请求。这是有道理的,这样许多客户端就不会向服务器发送大量请求,直到服务器无法处理为止。这尤其正确,那么您的请求的RTT(往返时间)相当长。

希望能有所帮助。干杯

一个好的起点是在Mozilla Firefox中使用Firebug这样的工具,它可以让你观察发送到服务器的请求并寻找瓶颈。

Firebug会分解请求的每个部分,这样你就可以看到你是否在与服务器交谈时遇到了问题,或者只是需要很长时间才能得到响应。

除了@Vern的回答,我还想说,如果可能的话,我会让服务器提前缓存数据,然后所有客户端都会从同一个缓存中提取数据,不需要单独的MySQL调用来访问每次更新的同一数据。然后,只要实际的数据库数据发生变化,PHP就会更新缓存。

所谓缓存,我的意思是让php写入服务器端的一个文件,然后客户端只需查看该文件的内容即可查看最新信息。可能有更好的缓存方法,但由于我以前从未亲自这样做过,这是我脑海中浮现的第一个解决方案。

相关内容

  • 没有找到相关文章

最新更新