Question

Je n'arrive pas à rendre mon script Perl stable sur le serveur.Voici le problème.

Lorsque le script est accédé plus de 5 fois par seconde, le serveur se bloque.Et quelque temps plus tard, le serveur se bloque pour toujours.SSH ne répond pas et je dois redémarrer le serveur.

J'utilise Apache avec mod_perl.

Le script est hébergé sur Virtual Dedicated Server sous Ubuntu.Je l'utilise via SSH.Ce sont les paramètres du serveur CPU:RAM 400 MHz:256 Mo

Le temps d'exécution maximum du script est de 200 millisecondes.

J'ai surveillé la charge du serveur avec l'utilitaire "top".Il n'affiche aucun problème, il s'agit des statistiques CPU lors d'un chargement de 5 scripts par seconde :

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

Quelles sont les options dont je dispose pour que le script fonctionne sans problème ?

C'est le résultat de ps aux | fgrep perl au moment du chargement :

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

MISE À JOUR

J'ai trouvé le goulot d'étranglement.J'ai utilisé le module DateTime plusieurs fois dans le code.Les méthodes suivantes du module DateTime semblent être très lentes.

  • nouveau()
  • maintenant()
  • ensemble(...)
  • delta_ms(...)

Je vais les remplacer par des analogues rapides.

Autre souci.L'instance mod_perl prend beaucoup de mémoire.Et je ne sais pas pourquoi.J'ai essayé d'exécuter un simple script Perl qui n'importe aucun module.Je l'exécute juste après le redémarrage d'Apache.Le script occupe 37 Mo de mémoire.Pourquoi cela arrive-t-il ?Savez-vous comment forcer mod_perl à ne pas utiliser la mémoire supplémentaire ?

Un script Perl standard, sans support mod_perl, prend 3 à 5 Mo de mémoire.

Les gars, merci pour votre aide, je ne m'attendais pas à une réponse aussi merveilleuse !

MISE À JOUR 2

J'ai trouvé un autre fait.J'ai créé un simple script Perl qui n'attend que 5 secondes.

#!/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);

Ensuite, je génère plusieurs de ces scripts en même temps.Le temps de furtivité (st) dans l'utilitaire principal passe de 0 % à 80 % et reste élevé jusqu'à ce que les scripts soient terminés.

D'où vient cette charge ?

De plus, comme je l'ai déjà mentionné, chaque instance Perl occupe 36 Mo de mémoire.

Était-ce utile?

La solution

Vos numéros de top semblent indiquer que d'autres processus en dehors de votre VM sont Throttling votre CPU, notez le dernier numéro, 87,2% st , qui indique qu'environ 87% de votre temps CPU est alloué par votre hyperviseur pour des tâches en dehors de votre machine virtuelle, même si votre machine virtuelle a des choses qu'il aimerait courir. Que cela soit lié à votre problème ou non est difficile à dire.

Au-delà de la mise à niveau de votre serveur comme suggéré par dérouleur, en utilisant un environnement de processus persistant comme suggéré par Zoul , il est possible que votre processus n'est pas liée au CPU du tout, mais est plutôt IO-lié, par exemple au réseau ou à votre accès au disque, ou lié à la mémoire. Il est difficile de dire sans plus de détails sur ce que votre script est en train de faire quand il est invoqué.

EDIT: Votre question mis à jour avec les informations sur votre utilisation de la mémoire est révélateur, comme chacun de vos processus veut 45M de RAM à lui tout seul, et partage 17M plus. Avec seulement 5 ou 6 processus en cours d'exécution, vous dépasser la quantité de RAM disponible. C'est une bonne quantité de mémoire pour un script Perl à utiliser la vanille, ce que ça fait avec elle?

Autres conseils

Ce n'est pas un serveur très grand. Se pourrait-il simplement fraie l'interpréteur Perl qui le rend mettre à genoux? Chargement perl (que je suppose est heureusement plus de 1 Mo) cinq fois par seconde pourrait être trop demander.

Bien sûr, il doit être mis en mémoire cache, mais il aura encore besoin d'initialisation avant de pouvoir exécuter.

Bien que, selon les normes actuelles, les spécifications du serveur ne soient pas impressionnantes, j'ai exécuté simultanément des tâches assez compliquées sur un matériel similaire.Cependant, j'ai utilisé une configuration très simple, n'exécutant que la configuration FreeBSD nécessaire.(Similaire à ce que vous pouvez réaliser en utilisant ArchLinux).Je soupçonne que vous n'avez pas effectué beaucoup de configuration personnalisée et que vous avez accepté les valeurs par défaut d'Ubuntu qui peuvent être trop lourdes pour ces spécifications.

Actuellement, je joue avec un Linode 360 ​​et les performances sont bonnes.

Maintenant, tout cela vise à énoncer une évidence :Nous avons besoin d’informations que vous possédez et que vous n’avez pas partagées avec nous.Configuration du serveur Web, empreinte mémoire du script + interpréteur, combien de fichiers sont ouverts etc etc.Essayez soit de fournir le plus petit script qui présente encore le problème, soit de fournir plus d'informations.

Mise à jour: Maintenant que je vois que tu utilises mod_perl:1) Avez-vous vérifié que toutes les bibliothèques nécessaires au script étaient préchargées au démarrage du serveur ?2) En recevez-vous variable won't stay shared messages dans le journal ?3) Avez-vous lu mod_perl Performances? (Chapitre 10 :Partager la mémoire pourrait être particulièrement pertinent).

En général, vous devez précharger les bibliothèques communes au démarrage du serveur Apache.En règle générale très simplifiée, plus les éléments restent partagés, plus vous pouvez tirer parti de votre serveur.Voir Fichier de démarrage dans mod_perl pratique.

De plus, je pense que 35 Mo par serveur, c'est un peu trop.Je pense que vous pourriez réduire cela si vous éliminiez les modules inutiles de la configuration Apache.Cependant, même si vous ne pouviez pas dire que tous les 35 Mo sont partagés et que le processus enfant maximum est de 50 Mo, vous devriez pouvoir gérer environ 20 clients à la fois.

Je viens de remarquer le script que vous testez.Vraiment, essayez de précharger CGI au démarrage du serveur en ajoutant les lignes suivantes à votre startup.pl:

use strict;
use warnings;

use CGI();

Deuxièmement, changez ce script en

#!/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);
}

Notez que vous n'avez jamais envoyé l'en-tête dans le script original (je déteste aussi appeler un CGI exemple $query donc j'ai pris la liberté de changer ça aussi).Voir également Référence Perl.

Signalez ensuite l'utilisation de la mémoire.

Finalement, pourquoi dors-tu 5 secondes ?AFAIK, le délai d'attente par défaut d'Apache pour un script est de 3 secondes.

Quel type d'interface n'utilise le script? Vous auriez certainement obtenir une meilleure performance si vous pouvez éviter de l'exécutable perl encore et encore, par exemple en utilisant FastCGI .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top