我们公司的系统在过去一周内一直存在运行缓慢的问题。经过一些调试,我能够通过按住 F5 让页面刷新多次来重现该问题。
页面冻结,无响应。通过查看服务器状态,我意识到有些请求被卡住了。
我对该过程进行了跟踪,它显示了以下消息:“flock(16,LOCK_EX”
这是 prework.c 的 httpd.conf,并且 keepalive 已关闭:
<IfModule prefork.c>
StartServers 4
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
好像请求陷入了僵局并永远卡在那里,这可能是系统变慢的原因吗?这是由某种错误配置引起的吗?
添加在:
我还意识到,当页面无响应时,MySQL 进程会休眠并且不执行任何操作。这种情况会在 60 秒后消失,我相信这是时间限制。
更新http.conf:
<IfModule prefork.c>
StartServers 2
MinSpareServers 2
MaxSpareServers 10
ServerLimit 256
MaxClients 100
MaxRequestsPerChild 4000
</IfModule>
答案1
您有一个 Web 服务器和一个数据库。您还拥有一些连接两者的东西,但您没有告诉我们。如果 flock 由 Apache 进程拥有,那么它可能是 mod_Perl、mod_PHP 或类似程序。这是您应该首先寻找罪魁祸首的地方。当然,在 PHP 上,唯一可以在不显式调用 flock() 的情况下锁定文件的东西是会话处理程序。如果您使用的是 PHP 和会话,请尝试非锁定处理程序否则,请检查您的代码中是否调用了 flock()。
请注意,在许多情况下,您看到的可能不是死锁,而只是大量缓慢的序列化请求。
或者,您可以考虑如何通过限制每个客户端的连接和请求数量来防止您创建的场景发生。
答案2
您的 MaxClients 设置得太高。确定设置的公式为:
(Total RAM – yMB)/xMB = MaxClients
其中x
Apache 进程的平均大小y
是您希望为其他进程保留的内存量。根据您的数字,并假设为其他进程预留 500M 的内存,您将得到:
(4000-500)/20=175
当您的请求数超过此限制时,您的服务器将开始交换磁盘,响应时间将飙升至几分钟,最终您的服务器将痛苦地死亡。注意:网页上的每个资产(即 .htm、每个 .css、每个图像文件等)都会生成一个“请求”,因此只需几次“页面点击”(或可能只有一次)就可能导致您达到限制!
将其设置为 100,看看会发生什么。同时,将其他设置恢复为默认设置,如果不是更低的话。例如:
StartServers 2
MinSpareServers 2
MaxSpareServers 10
可能会更好。