PHP是否可通过反向Ajax长轮询实现可扩展性?

5
我正在开发一个网站,该网站显示一些从数据库中获取的数据,这些数据会经常变化(队列状态和聊天对话状态)。我的当前设置是Apache/PHP/MySQL。自然而然地,我想避免每x秒轮询服务器,因为这不可扩展。我想使用反向ajax长轮询,但是,我已经读过Apache与此不兼容,因为它很快就会耗尽工作线程。有许多其他的Web服务器可以解决这个问题:nginx、tornado等。但是,我的问题是,PHP是我唯一了解的服务器端脚本语言。此外,我已经编写了一些PHP脚本,所以如果可能的话,我希望保留它们。只要我还能使用PHP,我就可以切换服务器。
但是在做更多的研究后,我发现人们说PHP(PHP-FPM?)也会为每个请求创建一个进程,这意味着如果我有数百/数千个打开的连接,就会有数百/数千个进程,这也是个问题。
我可以得出结论,使用PHP没有好的可扩展方式来制作长轮询网站吗?我应该放弃PHP并学习另一种服务器脚本语言吗?我可以继续使用当前的设置(Apache/PHP)开发长轮询,但我不希望脚本语言的选择对系统的可扩展性造成任何限制。那么我该怎么办?我在Web编程方面经验不是很丰富,如果有任何大师能给我一些指导,我将不胜感激!谢谢!

1
我自己没有做过,但使用js sockets是一个选项吗?也许可以使用node.js。浏览器对websockets的本地支持正在改进,但我猜jquery插件会处理它? - Ian Wood
我并不是真的考虑使用websocket,因为它不支持所有主流浏览器。我实际上已经研究了node.js,但据我所知,它仍然相对较新,因此框架支持更加有限。我目前正在考虑Django,这意味着我必须学习Python。我听说这个框架很好,但如果有办法避免性能损失,我仍然更愿意使用PHP。 - pinghsien422
我肯定会重新考虑使用Node.js - 对运行Node.js的服务器端口进行简单的Ajax请求可能就是解决办法。 - Ian Wood
2个回答

6

PHP在php-fpm模式下仍然会有限制,特别是当您的代码占用大量内存时。如果没有可用内存,您将无法运行数千个并行进程。但通常比mod_php更快,并且至少不需要PHP的HTTP请求由Web服务器处理,如果该Web服务器是nginx,则可以同时处理更多的HTTP请求。

使用php-fpm,您还将拥有等待请求的队列,在临时大流量的情况下可能会很有用,因为至少请求被排队,而不是被拒绝。

现在,长轮询操作对于nginx(或其他服务器)来说是可以的,但对于PHP来说不是。 PHP不是为长时间运行的服务器而构建的,每个请求都是一个新进程,这确实不是保持活动状态的正确选择。但“分而治之”(divide and rule)。您的长轮询任务可以在PHP应用程序附近运行,但不包括在PHP应用程序中。

作为示例,看一下jappix项目,这是一个PHP项目。但是你需要在某个地方放置一个XMPP服务器(例如ejabberd),以及一个带有nginx作为代理的BOSH服务器,并将其连接到端口80上的BOSH服务器(因此您可以通过nginx和ejabberd在端口80上使用xmpp聊天协议,而对于PHP方面则没有任何内容)。问题是要连接您的应用程序身份验证、标识等,这将需要通过扩展XMPP服务器配置来完成(以便它使用与您的PHP应用程序相同的LDAP服务器,例如)。
您的第二个长轮询问题是队列的状态。你可以找到一些与XMPP相关的扩展,或者可以对队列执行定期的ajax查询。避免在PHP应用程序上进行大量ajax请求的有用技术之一是基于Fibonacci数(这是一个例子)在ajax回调检查上重新安排下一个ajax检查的时间。因此,第一次下一个ajax调用将在1分钟后计划,然后是2分钟,然后是3m、5m、8m、13m、21m、34m、55m、89m、144m等。这个想法是,在页面加载后1分钟内检查新消息可能很重要。由于用户仍在阅读同一页(或喝咖啡、和朋友聊天、去度假而不关闭计算机等),我们可以越来越延迟下一次检查。这是一种假设用户并不真正活跃的方式。请注意,您可以通过其他方式检测用户活动并更改重新安排。

-1

PHP 不适合长轮询、Comet 和反向 Ajax 技术。你应该使用 Node.js。


1
请提供一些原因,而不是只回答一句话。 - pascalhein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接