Почему процесс apache mod_perl превращается в зомби?

Иногда процесс apache mod_perl помечается как «несуществующий» в «верхней» утилите, то есть становится зомби-процессом. Это правильное поведение? Я должен об этом беспокоиться?

Наш сценарий Perl очень прост, он не порождает никаких дочерних процессов. Процесс зомби исчезает довольно быстро. Apache2, Ubuntu.

Наша конфигурация apache находится здесь: apache_config.txt

Вот снимок сверху.

    PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
19525 www-data  20   0 55972  25m 4684 S 10.3  2.4   0:00.32 apache2
19486 www-data  20   0 52792  21m 4120 S  1.7  2.1   0:00.05 apache2
19538 www-data  20   0 52792  21m 4120 S  1.3  2.1   0:00.04 apache2
19539 www-data  20   0     0    0    0 Z  0.7  0.0   0:00.03 apache2 <defunct>
19481 www-data  20   0 52860  21m 4016 S  0.3  2.1   0:00.05 apache2
19521 www-data  20   0 52804  21m 3824 S  0.3  2.1   0:00.08 apache2

Это модули CPAN, которые я использую

CGI();
XML::LibXML();
DateTime;
DateTime::TimeZone;
Benchmark();
Data::Dump();
Devel::StackTrace();
DBD::mysql();
DBI();
LWP();
LWP::UserAgent();
HTTP::Request();
HTTP::Response();
URI::Heuristic();
MD5();
IO::String();
DateTime::Format::HTTP();
Math::BigInt();
Digest::SHA1();


top:
26252 www-data  20   0     0    0    0 Z  0.3  0.0   0:00.22 apache2 <defunct>

access.log with pid logged as the first parameter:
26252 85.124.207.173 - - [26/Dec/2009:22:16:42 +0300] "GET /cgi-bin/wimo/server/index.pl?location=gn:2761369&request=forecast&client_part=app&ver=2_0b191&client=desktop&license_type=free&auto_id=125CC6B6DAA HTTP/1.1" 200 826 0 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6.3; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"

3 разных зомби-процесса, регистрируемых по статусу сервера

Srv     PID     Acc     M   CPU     SS  Req ConnChild   Slot    Client      VHost           Request
32-0    1300    0/0/45  _   0.00    0   0   0.0 0.00    2.29    127.0.0.1   weather_server  OPTIONS * HTTP/1.0
100-0   1254    1/7/41  C   0.22    0   0   0.0 0.00    1.51    127.0.0.1   weather_server  OPTIONS * HTTP/1.0
29-0    1299    0/12/78 _   0.31    0   2   0.0 0.78    2.37    [my ip was here]    weather_server  GET /server-status HTTP/1.1

person Pavel    schedule 26.12.2009    source источник


Ответы (2)


Мое первое подозрение состоит в том, что вы действительно разветвляетесь, но, возможно, вы этого не понимаете. Можно ли включить свой код? Помните, что любые system или `` вызовы разветвляются. Это может легко происходить внутри модуля CPAN, даже если вы этого не осознаёте. Есть полезная информация о mod_perl и разветвлении (в том числе о том, как создаются зомби и как их избежать) здесь.

Обновление: попробуйте добавить это в свою конфигурацию:

# Monitor apache server status
ExtendedStatus On
<VirtualHost 127.0.0.1:80>
    <Location /server-status>
        SetHandler server-status
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Location>
</VirtualHost>

Затем измените Allow from на свой IP-адрес, после чего вы сможете посетить http://yourdomain.com/server-status и получите страницу со сводной информацией об apache. Попробуйте сделать это, когда увидите одного из зомби, и посмотрите, что, по мнению apache, делает этот процесс.

person Rob Van Dam    schedule 26.12.2009
comment
Спасибо, Роб. Я могу выслать вам весь исходный код. Вы хотите на это посмотреть? Однако здесь есть что прочитать, около 30 файлов. Я добавил в пост список модулей CPAN, используемых нашей системой, см. Выше. - person Pavel; 26.12.2009
comment
Кроме того, pid процесса зомби совпал с pid Apache2. Как мне кажется, зомби-процесс - это процесс Apache mod_perl, а не какой-то другой, порожденный кодом mod_perl. - person Pavel; 26.12.2009
comment
Нет, мне не нужно видеть весь ваш код. Спасибо за модули CPAN. Я не вижу там ничего, что явно разветвлялось бы, но раньше я был удивлен. Что касается pid, если вы выполните форк под mod_perl, и родительский, и дочерний будет казаться экземпляром apache, а не экземпляром вашего кода. Попробуйте добавить $ SIG {CHLD} = 'IGNORE'; где-то в самом начале вашего кода (возможно, в блоке BEGIN). Если это устраняет зомби, вы знаете, что что-то тайно разветвляется. - person Rob Van Dam; 26.12.2009
comment
Спасибо за этот совет! Я добавил $ SIG {CHLD} = 'IGNORE'; в блок BEGIN стартового скрипта (server.pl). К сожалению, неработающие процессы по-прежнему отображаются в топе. Смотрите мое обновление в теме. Я добавил верхнюю строку и запись access.log (я добавил pid в качестве первого параметра для записи журнала). PID совпадает, поэтому несуществующий процесс на самом деле является процессом mod_perl apache2. - person Pavel; 26.12.2009
comment
Роб, спасибо тебе большое! Я не знал о функции состояния сервера. Еще один инструмент в моем арсенале. Несколько раз удавалось ловить зомби. Но я не знаю, как дамп из sever-status может помочь нам найти источник проблемы. Я прикрепил 3 строки со страницы состояния сервера. Каждый из них принадлежит к разному зомби-процессу. - person Pavel; 27.12.2009
comment
Я хотел узнать, что думает apache об этих процессах, и это показало мне, что apache считает их нормальными рабочими процессами. В частности, одна из трех перечисленных вами страниц - это сама страница состояния сервера. Если это не была ошибка в вашем копировании / вставке, я почти уверен, что то, что вы видите, даже не связано с mod_perl. Я должен был спросить раньше, но как долго живут эти зомби? Если это очень быстро, я думаю, вы можете просто поймать apache, поскольку он решает, что ему не нужно так много детей, и убивает одного, в результате чего он перестает работать на секунду. - person Rob Van Dam; 27.12.2009
comment
Я на 90% уверен, что это зомби. Точно. Процессы с пометкой неработающие отображаются на мгновение вверху, очень быстро. Итак, подведем итоги. Знак несуществующего в моем случае не указывает на какие-либо проблемы с mod_perl и, вероятно, вообще нет проблем. Apache может вести себя подобным образом. Я задал этот вопрос, потому что системный администратор моего сервера сказал мне, что наличие неработающих процессов в верхней части является признаком неправильной конфигурации веб-сервера. Большое спасибо, ваши ответы очень профессиональные. Отметка вашего ответа как принятого. - person Pavel; 27.12.2009

Я тоже это вижу с помощью моего очень простого модуля mod_perl 2. Я не делаю ничего форк, просто записываю строку в клиентский сокет и возвращаю ОК. И все же на моей виртуальной машине CentOS 5.5 Linux появляется несуществующий процесс, а затем исчезает. Вот мой исходный код, и вы можете протестировать его с помощью "telnet yourhost 843" и нажатия ENTER:

package SocketPolicy;

# Run: semanage port -a -t http_port_t -p tcp 843
# And add following lines to the httpd.conf
# Listen 843
# <VirtualHost _default_:843>
#       PerlModule                   SocketPolicy
#       PerlProcessConnectionHandler SocketPolicy
# </VirtualHost>

use strict;
use warnings FATAL => 'all';
use APR::Const(-compile => 'SO_NONBLOCK');
use APR::Socket();
use Apache2::ServerRec();
use Apache2::Connection();
use Apache2::Const(-compile => qw(OK DECLINED));

use constant POLICY =>
qq{<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">

<cross-domain-policy>
<allow-access-from domain="*" to-ports="8080"/>
</cross-domain-policy>
\0};

sub handler {
        my $conn   = shift;
        my $socket = $conn->client_socket();
        my $offset = 0;

        # set the socket to the blocking mode
        $socket->opt_set(APR::Const::SO_NONBLOCK => 0);

        do {
                my $nbytes = $socket->send(substr(POLICY, $offset), length(POLICY) - $offset);
                # client connection closed or interrupted
                return Apache2::Const::DECLINED unless $nbytes;
                $offset += $nbytes;
        } while ($offset < length(POLICY));

        my $slog = $conn->base_server()->log();
        $slog->warn('served socket policy to: ', $conn->remote_ip());
        return Apache2::Const::OK;
}

1;
person Alexander Farber    schedule 22.10.2010