我们有一个带有 apache 2.2.14、PHP 5.3.2 的网络服务器。
PHP 使用 mod_fcgid 执行(见底部)。一切正常,但有时,我们仍然需要弄清楚是什么触发了这种情况,当 php 进程“旋转”时,它们仍然处于活动状态和孤立状态:apache 产生新的 php 进程,而旧的进程仍保留在系统上。杀死他们并不总是将他们踢走。更有可能是“apache2ctl graceful”将系统从这个陈旧的进程中解放出来。我们在错误日志中发现了这一点:[Tue Jun 18 20:49:54 2013] [warn] mod_fcgid: process 2009 graceful kill fail,从我发现的搜索中发送 SIGKILL 是很正常的,但这就是我在 apache 日志中发现的全部内容在其中一个过程中泄漏。
幸好这个事件很少发生,通常apache和php运行正常,在fcgid儿童更新期间没有问题。我们如何理解在这些情况下出了什么问题?
站点中的 mod_fcgid 配置:
<IfModule mod_fcgid.c>
SuexecUserGroup domain domain
<Directory /var/www/fomain.it/htdocs/>
AddHandler fcgid-script .php
FCGIWrapper /var/www/fcgi/domain.it/fcgi-starter-php .php
Options +ExecCGI -Indexes
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/fcgi/domain.it/>
AllowOverride None
Options +ExecCGI MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
</IfModule>
/var/www/fcgi/domain.it/fcgi-starter-php:
#!/bin/sh
PHPRC=/var/www/fcgi/domain.it/php/
export PHPRC
PHP_FCGI_CHILDREN=8
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /usr/lib/cgi-bin/php $1
我们目前找到了一种解决方法来避免服务器填满孤立的进程。您可以通过以下方式摆脱陈旧的流程:
apache2ctl graceful
并使用以下命令终止这些进程:
pkill -f -x /usr/lib/cgi-bin/php -P 1
编写和调度这两个命令(通过适当的检查)将避免服务器托管大量无用的过程,但问题仍然存在。
我没有真正的答案,但也许更多信息可以帮助解决问题。我想说,我在使用 PHP 5.3.5 的 Windows 服务器上遇到了同样的问题。
一些 cgi 进程在真正执行之后仍然是一种僵尸任务。他们甚至会忽略诸如 max_execution time 之类的设置。
目前我有一个预定的脚本来杀死这些旧进程。这个解决方案的问题是,即使是“正常”的 cgi 进程被杀死,也许检测进程的运行时间并且只有在它们超过 max_execution 时间时才杀死它们。
我有一个类似的问题,即 fcgid 在一段时间的活动后用完了可用的进程槽。
日志消息大致是:
我将问题归结为:
这是由于锁定不当引起的。就我而言,Apache 使用 fcntl() 锁定(默认情况下在 debian 上),所以我将其更改为flock() in
apache2.conf
:导致我找到解决方案的参考: https ://bz.apache.org/bugzilla/show_bug.cgi?id=53999
关于各种锁定选项的文档(fcgid 有一个警告建议不要将它与任何涉及线程的东西一起使用): https ://httpd.apache.org/docs/2.4/mod/core.html#mutex
正如 Thomas 在https://bz.apache.org/bugzilla/show_bug.cgi?id=53999中建议的那样更改为“sem”对我有用。
所以我建议任何人编辑他的 apache2.conf,评论 Mutex 行,然后输入: