У нас есть веб-сервер с apache 2.2.14, PHP 5.3.2.
PHP выполняется с использованием mod_fcgid (см. Внизу). Все работает нормально, но иногда, и нам все еще нужно выяснить, что вызывает это, когда процессы php «вращаются», они остаются активными и осиротевшими: apache порождает новые процессы php, а старые остаются в системе. Их убийство не всегда отбрасывает их. Более вероятно, что "apache2ctl graceful" освободит систему от устаревших процессов. Мы нашли это в журнале ошибок: [Вт, 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
создание сценариев и планирование этих двух команд (с надлежащими проверками) позволит избежать размещения на сервере множества бесполезных процессов, но проблема все еще существует.
Переход на "sem", как предложил Томас в https://bz.apache.org/bugzilla/show_bug.cgi?id=53999 работал у меня.
Поэтому я бы порекомендовал любому отредактировать его apache2.conf, прокомментировать строку Mutex и поставить:
# Mutex file:${APACHE_LOCK_DIR} default # Original debian config
Mutex sem # Solves orphaned PHP processes.
У меня нет точного ответа, но, возможно, дополнительная информация поможет решить проблему. Я хотел бы сказать, что у меня такая же проблема на сервере Windows с PHP 5.3.5.
Некоторые cgi-процессы остаются своего рода зомби-задачами после своего реального выполнения. Они даже игнорируют такие настройки, как max_execution time.
В настоящее время у меня есть запланированный сценарий, который убивает эти старые процессы. Проблема с этим решением заключается в том, что даже «нормальные» процессы cgi были убиты, возможно, было бы полезно определить время выполнения процессов и убить их только в том случае, если у них истекло время max_execution.
У меня была аналогичная проблема: у fcgid закончились доступные слоты процессов после некоторого периода активности.
Сообщение журнала было примерно:
[fcgid:warn] mod_fcgid: can't apply process slot for /var/www/cgi-bin/xxx/php-cgi, referer: ...
Я отследил проблему до следующего:
[fcgid:emerg] (35)Resource deadlock avoided: [client ....] mod_fcgid: can't get pipe mutex, referer: ...
что вызвано неправильной блокировкой. В моем случае Apache использовал блокировку fcntl () (по умолчанию в debian), поэтому я изменил это на flock () в apache2.conf
:
Mutex flock:${APACHE_LOCK_DIR} default
Ссылка, которая привела меня к решению: https://bz.apache.org/bugzilla/show_bug.cgi?id=53999
Документация по различным параметрам блокировки (у fcgid есть предупреждающий совет против использования его с чем-либо, что связано с потоками): https://httpd.apache.org/docs/2.4/mod/core.html#mutex