2010-01-07 1 views
7

Различные скрипты Perl (с учетом сервера) вызывают модуль Perl с множеством функций на веб-сайте. EDIT: Сценарии используют использование lib для ссылки на библиотеки из папки. В периоды занятости сценарии (а не библиотеки) становятся зомби и перегружают сервер.Как избежать зомби в скриптах CGI Perl, выполняемых под Apache 1.3?

Списки серверов:

319 ?  Z  0:00 [scriptname1.pl] <defunct>  
320 ?  Z  0:00 [scriptname2.pl] <defunct>  
321 ?  Z  0:00 [scriptname3.pl] <defunct> 

У меня есть сотни экземпляров каждого.

EDIT: Мы не используем вилку, систему или EXEC, помимо формирование директивы SSI

<!--#exec cgi="/cgi-bin/scriptname.pl"--> 

Насколько я знаю, в этом случае HTTPd сам будет владельцем процесса. MaxRequestPerChild установлен в 0, который не должен позволять родителям умирать до завершения дочернего процесса.

До сих пор мы полагали, что временное приостановление некоторых сценариев помогает серверу справляться с несуществующими процессами и препятствовать его падению, однако процессы зомби все еще формируются без сомнения. Очевидно, gbacon, по всей видимости, ближе всего к истине с его теорией о том, что сервер не справляется с нагрузкой.

Что может привести к тому, что httpd откажется от этих процессов? Есть ли какая-либо передовая практика, чтобы предотвратить это?

Благодаря

Ответ: Дело идет к Робу. Как он говорит, скрипты CGI, которые генерируют SSI, не будут обрабатывать эти SSI. Оценка SSI происходит до запуска CGI в цикле запросов Apache 1.3. Это было исправлено с Apache 2.0 и более поздними версиями, так что CGI может генерировать команды SSI.

Поскольку мы работали на Apache 1.3, для каждого просмотра страницы SSI превратились в несуществующие процессы. Хотя сервер пытался их очистить, он был слишком занят работающими задачами, чтобы добиться успеха. В результате сервер упал и стал невосприимчивым. В качестве краткосрочного решения мы рассмотрели все SSI и перенесли некоторые из процессов на клиентскую сторону, чтобы освободить ресурсы сервера и дать время для очистки. Позже мы обновились до Apache 2.2.

+9

Вам необходимо бросить трубную бомбу –

+5

Двойной выстрел из ствола также хорошо работает. – Nate

+0

Не позволяйте им есть ваш мозг. – Hai

ответ

2

Я только что видел ваш комментарий, что вы используете Apache 1.3 и которые могут быть связаны с вашей проблемой.

SSI может запускать CGI. Но CGI-скрипты, которые генерируют SSI, не будут обрабатывать эти SSI. Оценка SSI происходит до запуска CGI в цикле запросов Apache 1.3. Это было исправлено с Apache 2.0 и более поздними версиями, так что CGI может генерировать команды SSI.

Как я уже говорил выше, попробуйте запустить скрипты самостоятельно и посмотрите на выход. Они генерируют SSI?

Редактировать: Вы пытались запустить тривиальный скрипт CGI Perl, чтобы просто распечатать HTTP-ответ Hello World типа?

Затем, если это работает, добавить тривиальные директивы SSI, такие как

<!--#printenv --> 

и посмотреть, что происходит.

Редактировать 2: Только что понял, что, вероятно, происходит. Зомби возникают, когда дочерний процесс выходит и не получает. Эти процессы висят вокруг и медленно используют ресурсы в таблице процессов. Процесс без родителя - это осиротевший процесс.

Вы отказываетесь от процессов в своем сценарии Perl? Если да, добавили ли вы waitpid() родительскому?

У вас также есть правильный выход в сценарий?

CORE::exit(0); 
+0

Я запускал все сценарии через отладчик и устранял все ошибки и предупреждения. Они генерируют выход правильно. Мы все равно собирались обновиться до 2.0. Считаете ли вы, что это поможет? –

+0

Хорошо. Хорошая работа с отладчиком для устранения всех ошибок и предупреждений. Любой из ваших CGI Perl успешно завершен до завершения? –

+0

Как я уже сказал, они работают нормально. Помимо того, что они становятся зомби, они отлично работают. –

7

Больше Band-Aid, чем лучшая практика, но иногда вы можете уйти с простой

$SIG{CHLD} = "IGNORE"; 

Согласно perlipc documentation

На большинстве платформ Unix, то CHLD (иногда также известный как CLD) имеет особое поведение по отношению к значению 'IGNORE'. Установка $SIG{CHLD} на 'IGNORE' на такой платформе имеет эффект не создания процессов зомби, когда родительский процесс не выполняет wait() в своих дочерних процессах (, т. Е., дочерние процессы автоматически получаются). Вызов wait() с $SIG{CHLD}, установленный в 'IGNORE', обычно возвращает -1 на таких платформах.

Если вы заботитесь о выходе статусов дочерних процессов, вы должны собрать их (обычно называют «жатвы») по телефону wait или waitpid. Несмотря на жуткое имя, зомби - это всего лишь дочерний процесс, который вышел, но чей статус еще не получил.

Если ваши программы Perl являются дочерними процессами, становящимися зомби, то это означает, что их родители (те, которые ищут и забывают ваш код), должны очистить после себя. Процесс не может перестать превращаться в зомби.

+0

Большое спасибо G. Я не говорю, что я понимаю, как это работает, но я буду больше читать об этом. Я предполагаю, что CHLD переходит в вызывающий скрипт. Это правильно? –

+5

waitpid (-1, WNOHANG) не будет блокироваться, поэтому его можно вызывать периодически для сбора статуса выхода ребенка. Используйте цикл, подобный этому, чтобы пожинать всех ваших зомби: while (($ pid = waitpid (-1, WNOHANG))> 0) ... –

+0

@G Berdal Как запускаются ваши скрипты? Вы контролируете этот код? –

0

Поскольку у вас есть все биты самостоятельно, я бы предложил запустить отдельные сценарии по одному из командной строки, чтобы увидеть, можете ли вы определить те, которые висят.

В листинге ps отображается чрезмерное количество экземпляров одного конкретного скрипта?

Вы используете CGI с помощью mod_perl?

Редактировать: Просто просмотрел ваши комментарии относительно SSI. Не забывайте, что директивы SSI могут запускать сами скрипты Perl. Посмотрите, что CGI пытаются запустить?

Зависит ли он от другого сервера или службы?

+0

Я заметил те, которые висят. Почти все SSI на веб-странице становятся многочисленными экземплярами зомби. Они вызывают библиотеку для функций. Что я не уверен в том, кто считает их родителями? –

+0

Процесс, который называется SSI или CGI, является его родительским. Вы можете попробовать использовать 'ps' для поиска ppid (идентификатор родительского процесса), а затем посмотреть, что это за процесс, но я не уверен, что' ps' вернет ppid для зомби. (Похоже, должно быть, так как зомби должен знать, кто должен пожинать его, я просто не подтвердил, что он работает). Для меня вывод «ps -l» включает ppid; проверьте свою местную справочную страницу, если ваш 'ps' ведет себя по-другому. –

+0

@Dave, когда процесс зомби, по определению он не имеет ppid. –

 Смежные вопросы

  • Нет связанных вопросов^_^