Domanda

Non riesco a rendere stabile il mio script Perl sul server.Ecco il problema.

Quando si accede allo script più di 5 volte al secondo, il server si blocca.E qualche tempo dopo il server si blocca per sempre.SSH non risponde e devo riavviare il server.

Sto usando Apache con mod_perl.

Lo script è ospitato su un server dedicato virtuale sotto Ubuntu.Lo sto utilizzando tramite SSH.Questi sono la CPU Server Params:400 MHz RAM:256MB

Il tempo massimo di esecuzione dello script è di 200 millisecondi.

Ho monitorato il carico del server con l'utilità "top".Non presenta alcun problema, queste sono le statistiche della CPU durante un caricamento di 5 script al secondo:

Cpu(s): 12.1%us,  0.6%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si, 87.2%st

Quali opzioni ho per far funzionare lo script senza problemi?

Questo è il risultato di ps aux | fgrep perl al momento del caricamento:

ps aux | fgrep perl
www-data  2925  0.3  6.5  45520 17064 ?        R    17:00   0:01 /var/www/perl/loa -k start
www-data  2926  0.2  6.5  45520 17068 ?        R    17:00   0:01 /var/www/perl/loa -k start
www-data  2927  0.4  6.5  45676 17060 ?        R    17:00   0:01 /var/www/perl/loa -k start
www-data  2928  0.3  6.5  45676 17060 ?        R    17:00   0:01 /var/www/perl/loa -k start
www-data  2929  0.2  6.5  45676 17060 ?        R    17:00   0:01 /var/www/perl/loa -k start
www-data  2931  0.4  6.5  45740 17076 ?        R    17:00   0:01 /var/www/perl/loa -k start
root      2968  0.0  0.2   3196   656 pts/0    R+   17:06   0:00 fgrep perl

AGGIORNAMENTO

Ho trovato il collo di bottiglia.Ho utilizzato il modulo DateTime molte volte attorno al codice.I seguenti metodi del modulo DateTime sembrano essere molto lenti.

  • nuovo()
  • Ora()
  • impostato(...)
  • delta_ms(...)

Li sostituirò con analoghi veloci.

Un'altra preoccupazione.L'istanza mod_perl richiede molta memoria.E non ho idea del perché.Ho provato a eseguire un semplice script Perl che non importa alcun modulo.Lo eseguo subito dopo il riavvio di Apache.Lo script richiede 37M di memoria.Perché succede?Sai come forzare mod_perl a non utilizzare la memoria aggiuntiva?

Uno script Perl normale, senza supporto mod_perl, richiede 3-5 MB di memoria.

Ragazzi, grazie per l'aiuto così grande, non mi aspettavo una risposta così meravigliosa!

AGGIORNAMENTO 2

Ho scoperto un altro fatto.Ho creato un semplice script Perl che attende solo 5 secondi.

#!/usr/bin/perl
use CGI;

my $query= new CGI;
my $content = "5 second delay...\n";

$query->header(
    '-Content-type' => "text/plain",
    '-Content-Length' => length($content)
);

print $content;

sleep(5);

Quindi genero molti di questi script contemporaneamente.Il tempo di azione furtiva (st) nell'utilità principale aumenta dallo 0% all'80% e rimane elevato finché gli script non vengono completati.

Da dove viene questo carico?

Inoltre, come ho già detto, ogni istanza Perl occupa 36 MB di memoria.

È stato utile?

Soluzione

I tuoi numeri da top sembrano indicare che altri processi di fuori della tua VM sono throttling la CPU, notare l'ultimo numero, 87,2% st , che indica che circa il 87% del vostro tempo CPU viene allocata dal vostro hypervisor per le attività fuori della vostra macchina virtuale anche se il VM ha delle cose che vorrebbe correre. Se questo è legato al tuo problema o non è difficile da dire.

Al di là di aggiornare il proprio server come suggerito da rilassarsi , utilizzando un ambiente di processo persistente come suggerito da Zoul , è possibile che il processo non è vincolata CPU a tutti, ma è invece IO-bound, come ad esempio alla rete o al vostro accesso al disco, o la memoria-bound. E 'difficile da dire senza ulteriori dettagli su ciò che lo script è in realtà facendo quando viene invocato.

Modifica La tua domanda aggiornato con informazioni sul tuo utilizzo della memoria sta rivelando, come ognuno dei vostri processi vuole 45M di RAM tutto a se stesso, ed è la condivisione di più 17M. Con solo 5 o 6 processi in esecuzione, si sta superando la quantità di RAM disponibile. Questa è una buona quantità di memoria per uno script Perl vaniglia da usare, che cosa ci fa con esso?

Altri suggerimenti

Non è un server di grandi dimensioni. Potrebbe essere semplicemente la deposizione delle uova l'interprete Perl che lo rende in ginocchio? Caricamento perl (che ho felicemente presumo sia più di 1 MB) cinque volte al secondo potrebbe essere chiedere troppo.

Naturalmente, dovrebbe essere memorizzato nella cache, ma sarà ancora bisogno di inizializzazione prima di essere in grado di eseguire.

Sebbene, per gli standard odierni, le specifiche del server non siano impressionanti, ho eseguito contemporaneamente cose abbastanza complicate su hardware simile.Tuttavia, ho utilizzato un sistema molto semplice, eseguendo solo la configurazione necessaria di FreeBSD.(Simile a quello che puoi ottenere usando ArchLinux).Sospetto che tu non abbia eseguito molte configurazioni personalizzate e accettato le impostazioni predefinite di Ubuntu che potrebbero essere troppo pesanti per quelle specifiche.

Attualmente sto giocando con un Linode 360 ​​e le prestazioni vanno bene.

Ora, tutto questo vuole affermare l’ovvio:Abbiamo bisogno delle informazioni che hai e che non hai condiviso con noi.Configurazione del server web, impronta di memoria dello script + interprete, quanti file sono aperti ecc ecc.Prova a fornire lo script più piccolo che presenta ancora il problema o fornisci maggiori informazioni.

Aggiornamento: Ora che vedo che stai usando mod_perl:1) Ti sei assicurato che tutte le librerie necessarie allo script fossero precaricate all'avvio del server?2) Ne stai ricevendo qualcuno? variable won't stay shared messaggi nel registro?3) Hai letto mod_perl Prestazioni? (Capitolo 10:Condivisione della memoria potrebbe essere particolarmente rilevante).

In generale, dovresti precaricare le librerie comuni all'avvio del server Apache.Come regola pratica molto semplificata, più cose rimangono condivise, più puoi ottenere dal tuo server.Vedere File di avvio In Mod_perl pratico.

Inoltre, penso che 35 MB per server siano un po' troppi.Penso che potresti ridurlo se eliminassi i moduli non necessari dalla configurazione di Apache.Tuttavia, anche se non potessi, diciamo che tutti i 35 MB sono condivisi, più il processo figlio massimo è 50 MB, dovresti essere in grado di ospitare circa 20 client alla volta.

Ho appena notato lo script che stai testando.Davvero, prova a precaricare CGI all'avvio del server aggiungendo le seguenti righe al file startup.pl:

use strict;
use warnings;

use CGI();

Secondo, cambia lo script in

#!/usr/bin/perl

use strict;
use warnings;
use CGI ();

$| = 1;

handle_request();

sub handle_request {
    my $cgi = CGI->new;

    my $content = "5 second delay...\n";

    print $cgi->header('text/plain'), $content;

    sleep(5);
}

Nota che non hai mai inviato l'intestazione nello script originale (odio anche chiamare a CGI esempio $query quindi mi sono preso la libertà di cambiare anche quello).Guarda anche Riferimento Perl.

Successivamente segnalare l'utilizzo della memoria.

Infine, perché dormi 5 secondi?Per quanto ne so, il timeout predefinito di Apache per uno script è di 3 secondi.

Che tipo di interfaccia non utilizzare lo script? Si potrebbe certamente ottenere una migliore prestazione se si poteva evitare di correre ancora e ancora l'eseguibile perl, ad esempio utilizzando FastCGI .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top