繁体   English   中英

如何在不占用资源的情况下提供实时通知?

[英]How can I provide real-time notifications without tying up resources?

我正在使用AJAX在页面上实施长轮询 ,每当将新行插入数据库时​​我都希望更新该页面。 完成此操作的方式是使用jQuery的.ajax()调用,例如poll.php?ky=41 ,该查询多次查询数据库以查找ID > 41 (之间poll.php?ky=41等待),直到指定的超时时间。 如果有结果,或在给定的超时后,它将立即满足请求。

实际上,这将使隐藏连接始终与服务器保持打开状态,等待服务器响应以获取通知。

php53.cgi ,但是我使用DreamHost,并且在生成8个php53.cgi worker进程后,直到一次超时,才完成对我的网站的请求(即永久加载)。 这会影响我网站上的所有其他页面。 HTTP服务器是Apache 2.2.22-14。

为了缓解该问题,我减少了延迟和超时,使其更接近常规轮询,并且在一段时间没有更新时增加了更长的延迟。 这意味着通知可能会延迟几秒钟,但是到目前为止我的服务器运行良好。

我担心的是扩展的效果如何(或更确切地说,效果有多差)。

我的问题是:鉴于我位于共享主机(DreamHost)上,并且此页面必须与尽可能多的浏览器(移动设备除外)兼容,是否有更有效的方法从服务器获取即时“推送”通知?

或者,我还有什么其他选择? 我应该切换回常规轮询吗?

TL; DR

轮询速度很快,但是长轮询(在满足AJAX请求之前等待)会占用资源。 区别在于,长轮询将在到达后立即获得结果,而轮询仅在新信息传入后下一次发送AJAX请求时才进行选择。理想情况下,我想长轮询的优点而不会占​​用线程数,也不会导致其他用户等待页面投放。

在这种情况下,解决方案是仅使用常规轮询(例如,每500毫秒进行一次AJAX调用)来获取快速通知,而不是使用长轮询和占用线程。

从戴夫

许多请求比长请求要好处理。 由于线程从未真正死亡,因此它们只是被重用。 如果最后没有可用线程,它还将允许系统跳过一个周期。 现在,您将遇到共享主机上的apache + php配置问题。 之后,可以使用一个小的vps并交换到nginx或我的个人最爱切诺基,并使用phpfpm,然后可以构建为轮询循环保留的实际工作线程

由于线程始终处于打开状态,因此无需任何开销即可让轮询脚本完成然后重新启动(如果数据库连接正确完成,则池conns和prep语句之间几乎没有额外的数据库负载,甚至更好的内存缓存或类似语句也是如此)意味着您仅在运行期间锁定线程,然后立即将其释放以供其他进程使用并使用它,这是在回收8个线程时可以为8个以上的用户提供支持的方式。 除非使用实时套接字和守护程序,否则不必担心调用它总是比longpoll更有效。

到目前为止,问题已解决。

我认为在php中每个打开的连接都意味着一个正在运行的线程。 您必须使连接时间很短并使用轮询。

唯一的帮助是尽可能快地组织轮询,因此我将尝试为每个会话存储一个非常简单的信息队列,例如在apc_fetch/apc_store (如果您的应用程序仅运行一个apache)。 一个非常简单的页面has_update.php?session_id会读取状态行,并以尽可能最小的格式返回0或1,大多数情况下返回0。 因此,每秒5x不应太早成为性能问题。

当且仅当has_update.php返回1时,正常的ajax调用才会触发。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM