Назад | Перейти на главную страницу

Apache: осиротевшие процессы fcgi php

У нас есть веб-сервер с 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