所以我相信这可能以前曾被问过,但我想确保我得到正确的信息。
我正在运行一个带有Debian 5和Apache 2.2的360 Linode盒子。 我自己编译了一切(没有apt-get)。 每隔一段时间(每隔几个星期一次),我的服务器就会随机“崩溃”:它可能会达到100%的CPU(真的是400%,但你知道我的意思)并交给我们。 你不能SSH进来看看是什么问题,服务器本身停止接受连接。 解决这个问题的唯一方法就是重启机器。
最近发生的时间是24小时,12小时,10小时,8小时,6小时,4小时。最后,我在两天前把它锁起来了。 我注意到磁盘IO被抬高了,几乎没有任何内存了! 另外,有一个运行在3-4%RAM的httpd进程。 而通过船载,我的意思是当我做了ps -ef时,他们占据了整个屏幕。 如果你向上滚动,他们占用了我的SSH客户端的整个缓冲区。
所以我对代码做了一些调整,认为某些东西没有正确closures。 我在我的PHP中修正了内存问题,我开启了更细化的错误日志并修复了一堆错误,这在一定程度上似乎有所帮助。 大约每24小时发生一次事故。
我确信这是因为内存太less而造成的,我收到的命中量正在把我的服务器踢进交换。 由于需要交换的请求太多,磁盘IO通过屋顶射击,导致我的CPU使用率通过屋顶射击,导致我的服务器locking。
我试图解决这个问题:我做了一些研究,发现我应该使用prefork。 我在我的configuration环顾四周,找不到任何ServerLimit或MaxClients或类似的东西,所以我添加了一些“默认”值,我的服务器拒绝接受/任何/传入的连接。 实际上,prefork值会阻塞所有入站httpstream量(可能是因为我的服务器无法处理prefork?idk)。
我看到它的方式,我的服务器“曾经做”是好的,除了所有的这些Apache进程不断挂断和内存泄漏。 有没有办法在Apache进程上设置超时时间,或者对其中有多less个进行限制? 最好的解决scheme是使用prefork似乎很愚蠢; 我必须想象有更好的方法。
多谢你们
看来你正在学习PHP是一个内存pipe理的难题,而不是特别的可扩展性。
一些build议,没有特别的顺序:
如果您仍怀疑存在内存泄漏,则将MaxRequestsPerChild设置为非常低的值。
考虑购买更多的内存,现在360 megs真的不多。
尝试通过运行ps或top来查找httpd进程的平均大小,然后设置MaxClients,以使所有内容始终适合内存。 交换是一个死亡螺旋,你处理请求的速度越慢,因为它,越多的进程需要分叉,使用更多的内存。
如果你将php作为apache中的一个模块,它会为每个请求加载,无论是脚本还是静态文件(图像或CSS或.js或什么)。 考虑从一个单独的服务器提供静态内容,或者使用fastcgi或像nginx这样的反向代理来让apache只服务php来限制你必须保留在内存中的胖php实例的数量。
我猜你的机器内存不足。 在我的实验中,每个正在运行的apache进程都有可能占用大量内存。 如果你有php运行在apache的模块,请在php.ini中查看memory_limit =的值。 我有128M这是相当多的,当你只有10个Apache进程运行。 他们可能从一开始就没有这个数量,但是如果你的PHP应用程序内存泄露或者真的需要128M的话,你可以很容易的达到你的服务器的限制。
我的build议是:物理RAM除以memory_limit等于max_procs
如果你的内存真的很less,你可以尝试运行像lighttpd或nginx与PHP作为fastcgi过程,我没有使用nginx那么多,但我使用lighttpd分配,它有一个非常低的内存/ CPU的开销。
Lighttpd和PHP通过fastcgi教程
你有连接到任何数据库后端? 通常会发生的情况是,如果某些查询开始放慢速度,您将会有apache进程开始备份,并且在您的linode上给予的RAM量很less,会雪上加霜,导致CPU和负载出现问题。
另一件事,你提到你正在使用工作模式。 这很好,如果你100%确定你在PHP中使用的所有模块都是线程安全的。 实际的PHP安装手册build议不要使用它( PHP手册 )…无论你使用哪种模型,你需要确保你调整正确。 Tuning LAMP系统是一个很好的起点。 如果MaxClients未正确调整,Apache可能最终导致系统崩溃,因为它在stream量爆炸期间占用了所有内存。