Hallo,
sicher habt ihr noch meine Speicherprobleme mit xerces,soap und Co. in Erinnerung. Da sich hier in absehbarer Zeit keine Änderung abzeichnet, muss ich das Problem von der anderen Seite angehen. So gibt es jetzt einen Control-Prozess, der u.a. den Speicherverbrauch meines schlimmen Fingers überwacht. Bei einer einstellbaren Grenze gibts ein kill() und danach wird der Prozess neu gestartet. Eigentlich ganz einfach, aber hier komt der Haken:
Ich starte das Program mit 'nohup ./soapserver.pl &' sowohl von der Kommandozeile als auch aus meinem Control-Programm heraus (hier über system). Das gestartet Programm mach einen Port 8081 auf, um zu lauschen. Beim Start aus dem Control-Programm heraus erhalte ich aber die Meldung:
Can't create daemon: Die Adresse wird bereits verwendet at /home/interface/bidi/soapserver.pl line 23
Hmm. Das er beim kill() nicht gleich freigegeben wird, kann ja mal passieren, darum habe ich noch ein sleep(5) zwischen Kill und Start eingebaut. Hilft nix. Es geistert auch kein Zombi in der Prozessliste rum. Mache ich kill und Start über die Shell, brauche ich keine Wartezeit einplanen, der Start klappt immer sofort.
Also, was läuft hier falsch und wie mache ich es richtig? Anbei die drei subs. watchMemory() läuft dabei immer als eigener Process, weil vom Controller geforkt.
########## die Überwachungsroutine ############################## sub watchMemory{ # überwacht Speicherverbrauch vom soapserver.pl und startet ihn bei Bedarf neu my %env_fake; # Start und Stop wollen den Dienstnamen in einem Hash $env_fake{dienst} = "interface"; while(1){ my %res = &getServerInfo(); #print Dumper(%res); if($res{i_online} == 0 ) { print STDERR "Kein Serverprozess da .... \n"; sleep(10); next; } if ($res{i_memory} > $limit && $res{i_status} eq 'sleep'){ print STDERR " zu hoch (max: $limit) .... starte neu .... \n"; &stopServer(%env_fake); sleep(2); # bissel warten, bis Port wieder freigegeben wird &startServer(%env_fake); } sleep(10); } }
############### Stoppen #################### sub stopServer{ # Stoppt soapsever oder connector my $env = shift; my $pattern = $map{ $env->{dienst} }.".pl";
# keine Pattern gefunden? -> raus !! if($pattern eq '.pl'){return;}
my $kill = 0; # counter my $t = new Proc::ProcessTable; foreach my $p(@{$t->table}){ $kill += $p->kill(15) if $p->cmndline =~ /$pattern/ ; } my $res = &getStatus; return $res; }
################# Starten ################### sub startServer{ # starten soapserer oder connector my $env = shift;
if( $map{ $env->{dienst} } eq "soapserver" ){ system ("nohup /home/interface/bidi/soapserver.pl &"); }elsif( $map{ $env->{dienst} } eq "connector" ){ system ("nohup /home/interface/bidi/connector.pl &"); } my $res = &getStatus; return $res; }
Mit freundlichen Grüßen
Jens Puruckherr