2009-12-26 5 views
1

Occasionnellement, le processus apache de mod_perl est marqué "défunt" dans l'utilitaire "top", c'est-à-dire devient un processus zombie. Est-ce un comportement correct? Dois-je m'inquiéter à ce sujet?Pourquoi le processus apache mod_perl devient-il un zombie?

Notre script Perl est très simple, il ne génère aucun processus fils. Le processus zombie disparaît assez rapidement. Apache2, Ubuntu.

Notre config apache est ici: apache_config.txt

Voici un coup de pression de haut.

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 

Ce sont des modules CPAN J'utilise

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 différents processus zombie enregistrés par server-status

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 

Répondre

2

Mon premier soupçon est que vous êtes vraiment bifurquent, mais peut-être vous n » Je le réalise. Est-il possible d'inclure votre code? Rappelez-vous que tous les appels system sont en train de forker. Cela pourrait facilement se passer à l'intérieur d'un module CPAN sans que vous vous en rendiez compte. Il y a quelques informations utiles sur mod_perl et forking (y compris comment les zombies sont créés et comment les éviter) here.

Mise à jour: essayez d'ajouter ceci à votre config:

# 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> 

Et puis changer le Allow from être votre IP, alors vous pouvez visiter http://yourdomain.com/server-status et obtenir une page d'information sommaire sur apache. Essayez de le faire lorsque vous voyez l'un des zombies et regardez ce que fait apache ce processus.

+0

Merci, Rob. Je peux vous envoyer tout le code source. Voulez-vous le regarder? Cependant, il y a beaucoup à lire, environ 30 fichiers. J'ai ajouté à la publication la liste des modules CPAN utilisés par notre système, voir ci-dessus. – Pavel

+0

Je suis sûr qu'il n'y a pas d'appels système directs dans mon code. – Pavel

+0

De plus, le processus pid of zombie correspondait à Apache2 pid. Comme il me semble, le processus zombie est le processus Apache mod_perl, pas un autre - engendré par le code mod_perl. – Pavel

0

Je le vois aussi avec mon module mod_perl 2 très simple. Je ne fourche rien, il suffit d'écrire une chaîne sur le socket client, puis retournez OK. Et encore un défunt processus apparaît sur ma machine virtuelle CentOS 5.5 Linux, puis disparaît. Voici mon code source et vous pouvez le tester avec "telnet yourhost 843" et en appuyant sur ENTRÉE:

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;