我有一个配置了 MPM worker 和 php fast cgi 的 apache2 服务器。最近 apache 日志告诉我 MaxClients 经常被达到,尽管它已经相当高了。
我的服务器现在经常出现宕机,我在日志中看到一堆这样的行:
[Sun Mar 06 04:25:40 2011] [error] [client 50.16.83.115] FastCGI: comm with (dynamic) server "/var/local/fcgi/php-cgi-wrapper.fcgi" aborted: (first read) idle timeout (20 sec)
[Sun Mar 06 04:25:40 2011] [error] [client 50.16.83.115] FastCGI: incomplete headers (0 bytes) received from server "/var/local/fcgi/php-cgi-wrapper.fcgi"
我可以看到我的 php-cgi 进程非常大(平均约 70mb)。
这是我的 MPM 工作器的 Apache 配置:KeepAlive ON KeepAliveTimeout 2
<IfModule mpm_worker_module>
StartServers 5
MinSpareThreads 10
MaxSpareThreads 10
ThreadLimit 64
ThreadsPerChild 10
MaxClients 20
MaxRequestsPerChild 2000
</IfModule>
这是我的 fastcgi apache 配置:
<IfModule mod_fastcgi.c>
# One shared PHP-managed fastcgi for all sites
Alias /fcgi /var/local/fcgi
# IMPORTANT: without this we get more than one instance
# of our wrapper, which itself spawns 20 PHP processes, so
# that would be Bad (tm)
FastCgiConfig -idle-timeout 20 -maxClassProcesses 1
<Directory /var/local/fcgi>
# Use the + so we don't clobber other options that
# may be needed. You might want FollowSymLinks here
Options +ExecCGI
</Directory>
AddType application/x-httpd-php5 .php
AddHandler fastcgi-script .fcgi
Action application/x-httpd-php5 /fcgi/php-cgi-wrapper.fcgi
</IfModule>
这是我的 fastcgi 包装器:
#!/bin/sh
PHPRC="/etc/php5/apache2"
export PHPRC
PHP_FCGI_CHILDREN=8
export PHP_FCGI_CHILDREN
exec /usr/bin/php-cgi
任何帮助都将非常感激!
答案1
我不认为您的服务器配置与您的问题有关,但我们首先要解决这个问题:mod_fastcgi 将负责生成 PHP 进程,并且每个进程一次只提供一个请求(据我所知,我是 mod_fcgid 用户)。因此,要求 PHP 派生其他进程是没有意义的,您最好使用 PHP_FCGI_CHILDREN=0 来关闭此功能。
最近,apache 日志告诉我,MaxClients 经常被达到,尽管它已经很高了。
您的 MaxClients 是 20,在我的 MPM-worker 站点上,它大约是 5000-10,000!这非常低。
请记住,MaxClients 仅调节 Apache 进程池,并且 Apache 可以很好地扩展以服务数千个并发连接。
您可以使用 mod_fastcgi 选项单独控制 FastCGI 进程池。抱歉,我只能凭借对 mod_fcgid 的丰富经验来提供帮助。此进程池的大小大多数时候是 CPU 核心数的 1 倍到 4 倍。
[2011 年 3 月 6 日星期日 04:25:40] [错误] [客户端 50.16.83.115] FastCGI:与(动态)服务器“/var/local/fcgi/php-cgi-wrapper.fcgi”的通信已中止:(首次读取)空闲超时(20 秒)
您的应用程序在 20 秒内无法发送一个字节,这太慢了。您必须找到瓶颈。根据经验,如果平均负载较高,则很有可能是 CPU 或 I/O 受限(然后继续检查 CPU 使用率);否则,如果负载较低,请检查远程资源(数据库服务器、第三方 API 等)的等待情况。
答案2
您的脚本耗时超过 20 秒。请增加空闲超时值或调查它们耗时这么长的原因(例如等待数据库连接)。
答案3
据我所知,我安装的其中一个扩展存在问题。
答案4
您可以通过增加 PHP_FCGI_CHILDREN 的数量来解决这个问题,直到它耗尽您的所有内存或调试问题,为什么脚本执行时间太长。常见问题是:数据库速度慢,外部请求速度慢(使用 curl 或 fopen)。