【发布时间】:2013-05-17 13:03:10
【问题描述】:
我正在使用 AJAX 在一个页面上实现long polling,每当新行插入数据库时我想更新该页面。完成此操作的方法是使用 jQuery 的 .ajax() 调用,例如,poll.php?ky=41,它会多次查询数据库中 ID 为 > 41 的行(中间有一小段等待),直到指定的超时。如果有结果,或者在给定的超时之后,它将立即完成请求。
实际上,这使隐藏的连接始终对服务器开放,等待它响应,以便获得通知。
这可行,但我正在使用 DreamHost,并且在生成了 8 个 php53.cgi 工作进程之后,直到一次超时,对我的站点的请求都没有得到满足(即永远加载)。这会影响我网站上的所有其他页面。 HTTP 服务器是 Apache 2.2.22-14。
为了缓解这个问题,我减少了延迟和超时,使其更接近于常规轮询,并在一段时间没有更新时增加了更长的延迟。这意味着通知可能会延迟几秒钟,但到目前为止我的服务器运行良好。
我担心的是这会扩展得有多好(或者更确切地说,有多差)。
我的问题是:鉴于我在共享主机 (DreamHost) 上,并且此页面必须与尽可能多的浏览器兼容(移动设备除外),是否有更有效的方式来获取即时“推送”通知来自服务器?
或者,我还有什么其他选择?我应该切换回常规投票吗?
TL;博士
轮询速度很快,但长轮询(在完成 AJAX 请求之前等待)占用资源。不同的是,长轮询一到就会得到结果,而轮询只会在新信息进来后下一次发送 AJAX 请求时才取到它。理想情况下,我希望长轮询的优势不会占用线程并导致其他用户在页面提供之前等待。
【问题讨论】:
-
@ZachLeighton 谢谢,在此之前我已经梳理过该页面,但我需要有关如何克服我所面临的限制的具体信息。
-
你有没有想过使用 Websockets 来代替?
-
许多请求比长请求处理得更好。由于线程永远不会真正死亡,它们只会被重用。如果最终没有可用线程,它还将允许系统跳过一个循环。现在在某个时候,您会遇到共享主机上的 apache+php 配置问题。之后,也许可以使用一个小型 vps 并切换到 nginx 或我个人最喜欢的 cherokee 并使用 phpfpm,然后您可以构建一个为您的轮询循环保留的实际工作线程
-
由于线程始终处于打开状态,因此允许轮询脚本完成然后重新启动没有任何开销(如果数据库连接正确完成,则池化 conns 和 prep 之间将几乎没有额外的数据库负载-statements 甚至更好的 memcached 或类似的)意味着您只在运行期间锁定线程,然后立即释放它以供其他进程拾取并使用它这是您可以在 8 个线程上支持超过 8 个用户的方式,因为它们被回收.除非你使用实时套接字和守护进程,否则不要担心调用它总是比 longpoll 更有效
标签: php mysql jquery push-notification