Pregunta

No puedo hacer que mi script Perl se ejecute de manera estable en el servidor.Aquí está el problema.

Cuando se accede al script más de 5 veces por segundo, el servidor se congela.Y algún tiempo después el servidor se cuelga para siempre.SSH no responde y tengo que reiniciar el servidor.

Estoy usando Apache con mod_perl.

El script está alojado en un servidor virtual dedicado en Ubuntu.Lo estoy operando a través de SSH.Estos son la CPU de parámetros del servidor:Ram de 400 MHz:256 megas

El tiempo máximo de ejecución del script es de 200 milisegundos.

He monitoreado la carga del servidor con la utilidad "top".No muestra ningún problema, estas son las estadísticas de la CPU durante una carga de 5 scripts por segundo:

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

¿Qué opciones tengo para que el script funcione sin problemas?

Este es el resultado de ps aux | fgrep perl en el momento de la carga:

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

ACTUALIZAR

He encontrado el cuello de botella.He estado usando el módulo DateTime muchas veces en el código.Los siguientes métodos del módulo DateTime parecen ser muy lentos.

  • nuevo()
  • ahora()
  • colocar(...)
  • delta_ms(...)

Voy a sustituirlos por análogos rápidos.

Otra preocupación.La instancia mod_perl requiere mucha memoria.Y no tengo idea de por qué.Intenté ejecutar un script Perl simple que no importa ningún módulo.Lo ejecuto justo después de reiniciar Apache.El guión ocupa 37 millones de memoria.¿Por que sucede?¿Sabes cómo forzar que mod_perl no use la memoria extra?

Un script Perl normal, sin soporte mod_perl, ocupa entre 3 y 5 M de memoria.

Chicos, gracias por tanta ayuda, ¡no esperaba una respuesta tan maravillosa!

ACTUALIZACIÓN 2

He encontrado un hecho más.Creé un script en Perl simple que solo espera 5 segundos.

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

Luego genero muchos de estos scripts al mismo tiempo.El tiempo de sigilo (st) en la utilidad superior salta del 0 % al 80 % y se mantiene alto hasta que se completan los scripts.

¿De dónde viene esta carga?

Además, como ya mencioné, cada instancia de Perl requiere 36 M de memoria.

¿Fue útil?

Solución

Sus números de top parecen indicar que los otros procesos fuera de la máquina virtual se estrangulación su CPU, tenga en cuenta el último número, 87,2% st , que indica que alrededor del 87% de su tiempo de CPU se está asignando por su hipervisor para tareas fuera de su máquina virtual a pesar de que su VM tiene cosas que le gustaría correr. Si esto está relacionado con su problema o no es difícil de decir.

Más allá de actualizar el servidor según lo sugerido por desenrollado , utilizando un entorno de proceso persistente como lo sugiere Zoul , es posible que su proceso no es CPU obligado en absoluto sino que es IO-consolidados, como los de la red o para su acceso al disco o memoria de ruedas. Es difícil de decir sin más detalles sobre lo que su escritura está haciendo realidad cuando se invoca.

EDIT: Su pregunta actualizado con información sobre el uso de memoria es revelador, como cada uno de sus procesos quiere 45M de RAM todo a sí mismo, y está compartiendo 17M más. Con tan solo 5 o 6 procesos en ejecución, que está superando la cantidad de memoria RAM disponible. Esa es una buena cantidad de memoria para un script Perl vainilla de usar, ¿qué hace con ella?

Otros consejos

Eso no es un servidor muy grande. Podría ser simplemente el desove el intérprete Perl que hace que arrodillarse? Cargando Perl (que yo supongo es felizmente más de 1 MB) cinco veces por segundo podría ser pedir demasiado.

Por supuesto, se debe almacenar en caché, pero todavía tendrá la inicialización antes de poder ejecutar.

Si bien, según los estándares actuales, las especificaciones del servidor no son impresionantes, he ejecutado cosas bastante complicadas simultáneamente en hardware similar.Sin embargo, utilicé una configuración muy básica, ejecuté solo lo necesario para FreeBSD.(Similar a lo que puedes lograr usando ArchLinux).Sospecho que no realizó muchas configuraciones personalizadas y aceptó los valores predeterminados de Ubuntu que pueden ser demasiado pesados ​​para esas especificaciones.

Actualmente estoy jugando con Linode 360 ​​y el rendimiento es bueno.

Ahora bien, todo esto pretende decir lo obvio:Necesitamos información que usted tiene y que no ha compartido con nosotros.Configuración del servidor web, uso de memoria del script + intérprete, cuántos archivos están abiertos, etc., etc.Intente proporcionar el script más pequeño que aún presente el problema o proporcione más información.

Actualizar: Ahora que veo que estás usando mod_perl:1) ¿Se ha asegurado de que todas las bibliotecas que necesita el script estén precargadas al iniciar el servidor?2) ¿Estás recibiendo alguna variable won't stay shared mensajes en el registro?3) ¿Has leído? mod_perl Rendimiento? (Capítulo 10:Compartir memoria podría ser especialmente relevante).

En general, debes precargar las bibliotecas comunes al inicio del servidor Apache.Como regla general muy simplificada, cuanto más cosas se compartan, más podrás sacar de tu servidor.Ver Archivo de inicio en Mod_perl práctico.

Además, creo que 35 MB por servidor es demasiado.Creo que podría reducirlo si eliminara los módulos innecesarios de la configuración de Apache.Sin embargo, incluso si no pudiera, digamos que se comparten todos los 35 MB, más el proceso secundario máximo es de 50 MB, debería poder acomodar a unos 20 clientes a la vez.

Acabo de notar el script que estás probando.De verdad, intenta precargar CGI al iniciar el servidor agregando las siguientes líneas a su startup.pl:

use strict;
use warnings;

use CGI();

En segundo lugar, cambie ese script a

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

Tenga en cuenta que nunca envió el encabezado en el script original (también odio llamar a un CGI instancia $query así que me tomé la libertad de cambiar eso también).Ver también Referencia de Perl.

Informe el uso de la memoria después de eso.

Finalmente, ¿por qué duermes 5 segundos?AFAIK, el tiempo de espera predeterminado de Apache para un script es de 3 segundos.

¿Qué tipo de interfaz no utilizar el script? Que sin duda obtener un mejor rendimiento si se pudiera evitar ejecutar el ejecutable perl una y otra vez, por ejemplo mediante el uso de FastCGI .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top