首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP和CPU -聊天+通知的处理

PHP和CPU -聊天+通知的处理
EN

Stack Overflow用户
提问于 2010-08-26 16:33:56
回答 2查看 1K关注 0票数 1

我的站点有一个PHP进程在运行,对于每个打开的窗口/选项卡,它最多在1分钟内运行,并返回在线或离线的通知/聊天消息/人员。当JavaScript获得输出时,它会再次调用相同的进程,依此类推。

这就像Facebook聊天。

但是,它在运行时似乎占用了太多的CPU。你有没有想过Facebook是如何处理这个问题的?他们怎么做才能使他们的进程不会占用太多的CPU并使他们的服务器宕机?

我的进程有一个"while(true)",最后有一个"sleep(1)“。在周期内,它检查通知,检查当前在线人员是否离线/更改状态,读取未读消息等。

如果你需要更多关于我的流程如何工作的信息,请告诉我。

从"system()“调用其他PHP(并等待其输出)可以缓解这个问题吗?

我之所以这样问,是因为它使其他进程检查通知,并在完成时刷新,而主PHP只是收集结果。

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-26 16:58:10

我认为你的主要问题是并行性。当100+用户有一个开放的HTTP请求时,Apache和PHP并不擅长这样的任务。

如果在您的while(true)中,您将0.1秒花在与CPU相关的工作负载上(检查更改状态或其他有用的事情),并在睡眠上花费1秒,这将导致在聊天中有10个用户在线时,CPU负载为100%。因此,为了使用这种聊天模式为更多用户提供服务,您必须在while(true)周期中优化工作负载和/或将睡眠间隔从1秒提高到3秒或更长。我在很多年前写的一个基于http的聊天系统中也遇到了同样的问题,在某个时候,太多的并行mysql-select减慢了聊天速度,在系统上产生了大量负载。我所做的是为共享内存中的消息和状态信息实现一个快速的“环形缓冲区”(sysv )--今天我可能会使用APC或memcached。所有操作都会在缓冲区中写入和读取,缓冲区本身会定期“刷新”到数据库中以持久化它(但每个用户每秒刷新一次的频率很低)。如果不需要持久化,当然可以省略一个后端。通过这种方式,我能够将我可以服务的用户数量增加大约500%。

但是一旦你解决了这个问题,你就会面临另一个问题:可用的系统内存(100+ apache每个进程大约5MB)和进程上下文切换开销。你的进程越活跃,你的操作系统在分配“足够公平”的CPU插槽AFAIK上的开销就越大。

您将会发现,仅使用apache和PHP很难针对您的用例进行有效的扩展。不过,有一些开源工具可以提供帮助,包括客户端和基于服务器的。我记得有一个将服务器放在apache之前,并在内部对消息进行排队,同时与javascript客户端进行非常有效的多套接字通信,从而使真正的“推送”事件成为可能。不幸的是,我不记得任何名字,所以你将不得不研究或希望在堆栈溢出社区,以使我的大脑丢弃了所有;)

编辑:嗨·努诺

评论字段的字符太少,所以我在这里回复。

让我们再来看看并行的10个用户:每个周期10*0.1秒的CPU时间(假设)大约是1.1秒(1秒睡眠+ 0.1秒执行)内的CPU时间总和。这个1/ 1.1,我大胆地将其舍入为100%的cpu利用率,尽管它只有%90.9

如果在不是1.1秒而是3.1秒(3秒睡眠+ 0.1秒执行)的时间段内存在10*0.1s的CPU时间,则计算结果为1/ 3.1 = %32

这是合乎逻辑的。如果您的检查周期查询后端的速度慢三倍,则系统上的负载只有三分之一。

关于共享内存:这个名称可能暗示了它,但如果您使用好的ID作为缓存区域,比如每个对话或用户一个ID,那么您将在共享内存中拥有私有区域。数据库表还依赖于您提供良好的ID来将私有数据与公共信息分开,因此这些都应该是现成的:)

我也不会再“分裂”了。需要并行“处理”的PHP进程越少,对您的系统和您来说就越容易。除非你看到它是绝对有意义的,因为一种类型的通知比另一种类型的通知需要更多的查询资源,并且你希望有不同的刷新时间或类似的东西。但即使是这样,也可以在whyile循环中决定。用户“离开”-status可以每30秒检查一次,而他可能写的消息可以每3秒检查一次。没有理由创建更多的周期。只是不同的计数器变量,或者在模运算中使用右除数。

PHP的发明者说,他认为人类控制并行进程的能力太有限了:)

编辑2

好的,让我们建立一个公式。我们有以下变量:

执行持续时间(e)睡眠持续时间(s)一个周期持续时间(C)并发用户数(u) CPU负载(l)

CPU l=u_e /c#表示可用时隙c适合由30个并发用户产生的c=e+s负载的“频率”。l=u_e / (e+s)

对于30个用户,假设您有0.1s的执行时间和1秒的休眠l=30*0.1 / (0.1 + 1) l=2.73 l=利用率为273%(也就是您需要3个核心:P)

超过卡帕布。你的CPU测试周期会比你预期的运行时间更长。总响应时间将增加( cpu运行过热)

票数 3
EN

Stack Overflow用户

发布于 2010-08-26 19:14:00

PHP会阻止所有sleep()和system()调用。您真正需要的是研究pcntl_fork()。幸运的是,我在十多年前就遇到了这些问题,你可以看看我的大部分代码。

我需要一个PHP应用程序,它可以连接到多个IRC服务器,坐在无限的IRC聊天室里,控制、交互和接收来自人们的命令。所有这一切都是以流程高效的方式完成的。

你可以在http://sourceforge.net/projects/phpegg/上查看整个项目,你想要的代码在source/connect.inc中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3573384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档