Какой vhost получает SIGKILL в Apache 2.2/PHP 5.3.3?
У меня есть сервер Linux с 16 ГБ оперативной памяти и 8 ядер. Он никогда не переходит в своп, и загрузка процессора не превышает ~1,5. Я считаю, что можно с уверенностью сказать, что есть много возможностей.
Иногда я получаю некоторые [warn] mod_fcgid: process 28341 graceful kill fail, sending SIGKILL
,
В Apache/2.2.15 (CentOS 6.3) mod_fcgid/2.3.7 все нижеуказанные настройки mod_fcgid отсутствуют, поэтому по умолчанию:
FcgidMinProcessesPerClass
FcgidMaxProcessesPerClass
FcgidMaxProcesses
FcgidIdleTimeout
FcgidProcessLifeTime
FcgidIdleScanInterval
FcgidOutputBufferSize
Я хочу определить, в каком vhost процессы получают SIGKILLed. Поэтому я загрузил mod_status и включил ExtendedStatus. Я настраиваю log_server_status запускаться каждую минуту, поскольку я не могу позволить себе вручную перезагружать страницу /server-status/ и одновременно следить за журналами весь день, ожидая, когда произойдет SIGKILL.
Но вывод log_server_status не очень полезен. Это все, что я вижу в журналах, созданных скриптом:
180131::::
all the way to
235501::::
235601::::
235701::::
235801::::
235901::::
Я хочу разыскать ответственных за SIGKILL. Как мне это сделать? Я делаю что-то не так в отношении log_server_status? Вывод кажется бесполезным...
2 ответа
Мне приходилось ежедневно вручную расчесывать журналы ошибок apache для записей, которые происходили в то же время, когда сообщения SIGKILL регистрировались в системном журнале. Это позволило мне узнать, какие процессы vhosts становились SIGKILLED. Я начал отслеживать (вручную), к каким файлам обращались в указанные временные метки на этих vhosts, и через несколько дней у меня было достаточно данных, чтобы отследить, какие php-файлы вызывали ошибки.
Проблема решена, и я больше не получаю предупреждений SIGKILL.
В качестве примечания, которое относится только к моему конкретному случаю: предупреждения поступили от записей maronto cron, которые не смогли завершиться в максимально допустимое время для выполнения скрипта. Поэтому я увеличил время выполнения до 180 (на пару дней), и эти задания cron начали успешно завершаться. Затем я сократил максимально допустимое время, и теперь они могут финишировать менее чем за 60 секунд. Длительное время выполнения было связано с тем, что несколько заданий не выполнялись в течение длительного времени, и они имели большую, чем обычно, нагрузку для обработки.
Похоже, вы запускаете PHP через mod_fcgid. Пока одна и та же оболочка используется для запуска интерпретатора PHP для всех vhosts, процессы, порожденные mod_fcgid, используются перекрестно, так как у вас, похоже, нет специфичных для vhost директив для fcgid. Они остаются запущенными после запуска и повторно используются для запуска любого кода PHP, переданного им для обработки (что является самой солью mod_fcgid BTW). Обратитесь к документации mod_fcgid для получения подробной информации.
Есть задокументированная ошибка, нарушающая это поведение и приводящая к ситуации, когда процессы PHP могут порождаться для каждого vhost без учета любых определенных ограничений для класса при определенных условиях, но эта ошибка относится только к старой версии модуля 2.3.6, это нежелательное поведение и было исправлено в 2.3.7.
Кроме этого, предупреждения журнала, которые вы видите, не связаны с исчерпанием ресурсов, это обычное действие mod_fcgid. mod_fcgid периодически завершает запущенные процессы (либо после простоя, определенного времени жизни или после определенного количества запросов). Прекращение происходит путем отправки SIGTERM процессу. Если процесс по какой-то причине не может вовремя обработать SIGTERM (он может быть слишком занят, но может просто перехватывать и игнорировать запросы SIGTERM), он принудительно завершается с помощью SIGKILL - об этом и предупреждение.
Если вы недовольны временем окончания процесса, просто настройте соответствующие параметры с помощью директив FcgidIdleTimeout, FcgidProcessLifetime и FcgidMaxRequestsPerProcess.