使用Ajax和PHP进行长轮询 - Apache冻结

时间:2013-04-18 10:38:25

标签: php ajax apache long-polling

我们尝试在公司的ERP中实施基于长轮询的通知服务。与Facebook通知类似。

使用的技术:

  • PHP的timeout在每次循环迭代中设置为60秒和1秒sleep
  • 用于AJAX处理的jQuery。
  • Apache as web server。

经过近一个月的编码,我们开始投入生产。部署后几分钟我们不得不回滚所有内容。事实证明,我们的服务器(8个核心)无法处理来自20名员工的长请求,每个使用约5个浏览器选项卡。 例如:用户使用我们的ERP打开了3个选项卡,每个选项卡上都有一个长轮询AJAX。打开第4个选项卡是不可能的 - 它会挂起,直到前3个中的一个被杀死(因此AJAX停止)。

我们认为,“Apache限制”。所以我们去谷歌搜索。我找到了一些关于Apache的MPM模块和配置的信息,所以我试了一下。我们的服务器使用prefork MPM,显示为apachectl -l。所以我在配置中更改了几行,看起来像这样:

<IfModule mpm_prefork_module>
    StartServers          1
    MinSpareServers       16
    MaxSpareServers      32
    ServerLimit          50%
    MaxClients          150
    MaxClients           50%
    MaxRequestsPerChild   0
</IfModule>

有趣的是,它可以在我的本地机器上使用类似的配置。在服务器上,看起来Apache忽略了配置,因为MinSpareServers设置为16,重启后会激活8。你不知道该怎么做。

2 个答案:

答案 0 :(得分:4)

Passerby在上一篇文章的第一条评论中给了我很好的指导,看看我们是否达到了与一台服务器的最大浏览器连接。

事实证明,每个浏览器都有这些限制,你无法改变它们(据我所知)。 我们做了一个解决方法,使其工作。

我们假设我从

获取AJAX数据
http://domain.com/ajax

为避免达到最大浏览器连接,每个长轮询AJAX都会连接到随机子域,例如:

http://31289.domain.com/ajax
http://43289.domain.com/ajax

等等。 DNS服务器上有一个从*.domain.comdomain.com的通配符,子域是唯一的随机数,由JS在每个选项卡上生成。

有关详细信息,请查看this thread

AJAX Same Origin Security也存在一些问题,但我们设法使用JSPHP方面的相应标头解决了问题。

如果您想了解有关标题的详情,请查看here on StackOverflowhere on Mozilla Developer's page。谢谢!

答案 1 :(得分:2)

我已成功实施了长轮询的LAMP设置。要记住两件事,linux的php内部执行时钟不会被'usleep()'函数改变或增加。因此,只有在获得数据的时间比正常时间长,或者可能用于Windows设置的罕见边缘情况下,才需要设置最大执行时间。此外,长时间轮询时请记住,一旦超过20秒,您就很容易发生浏览器超时。

其次,您需要验证您的会话是否未锁定(如果正在使用会话)。

Apache真的不应该对你要做的事情有任何问题。虽然,我承认像nginx或特定于ajax的网络服务器这样的网络服务器可以更好地处理并发连接。如果您可以发布ajax处理程序的代码,我们可以找出问题所在。

利用子域,或者像其他线程所建议的那样 - 在不同的端口上有多个Web服务器,请记住,您可能会遇到JavaScript域安全问题。

我说,在遇到问题并用尽所有其他选项之前,请不要更改apache配置;在发送另一个请求之前,请小心PHP会话,并确保AJAX正在等待响应;)