Pergunta

Eu consigo fazer com que meu script Perl de execução estável no servidor.Aqui está o problema.

Quando o script é acessado mais de 5 vezes por segundo, o servidor congela.E algum tempo mais tarde, o servidor trava para sempre.O SSH não responde e eu tenho que reiniciar o servidor.

Eu estou usando o Apache com mod_perl.

O script está hospedado em Servidor Dedicado Virtual no Ubuntu.Eu estou operando através de SSH.Estes são o servidor de parâmetros CPU:400 MHz RAM:256 MB

O máximo de tempo de execução do script é de 200 milissegundos.

Tenho monitorado a carga do servidor com o "top" utilitário.Ele não apresenta quaisquer problemas, este é o CPU estatísticas durante uma carga de 5 de 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

Que opções eu tenho para fazer o script funcionar sem problemas?

Este é o resultado de ps aux | fgrep perl no momento do carregamento:

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

ATUALIZAÇÃO

Eu encontrei o gargalo.Estou usando o módulo DateTime muitas vezes em torno do código.Os seguintes métodos de módulo DateTime parecem ser muito lento.

  • novo()
  • agora()
  • conjunto de(...)
  • delta_ms(...)

Eu estou indo para substituí-los com rapidez análogos.

Outra preocupação.mod_perl exemplo tem um monte de memória.E eu não tenho idéia do porquê.Eu tentei executar um script perl simples que não importa todos os módulos.Eu executá-lo apenas depois de reiniciar o apache.O script pega 37M de memória.Por que isso acontece?Você sabe como força mod_perl não usar a memória extra?

Uma regulares perl script, sem suporte a mod_perl, leva de 3-5M da memória.

Galera, obrigado por tanta ajuda, eu não estava esperando essa maravilhosa resposta!

ATUALIZAÇÃO 2

Eu tenho encontrado mais um fato.Eu criei um script perl simples, que apenas aguarda 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);

Então eu spawn muitos desses scripts ao mesmo tempo.Stealth tempo (st) no topo utilitário salta de 0% a 80% e permanece elevada até que os scripts são feitas.

De onde vem essa carga vem?

Também, como já mencionado, para cada perl de exemplo tem 36M de memória.

Foi útil?

Solução

Seus números de top parece indicar que outros processos fora da sua VM estão estrangulando sua CPU, observe o último número, 87,2%st, o que indica que cerca de 87% do seu tempo de CPU está sendo alocado pelo seu hipervisor para tarefas fora da sua VM, mesmo que sua VM tenha coisas que gostaria de executar. Se isso está relacionado ao seu problema ou não, é difícil dizer.

Além de atualizar seu servidor, conforme sugerido por desenrolar, usando um ambiente de processo persistente, conforme sugerido por zoul, é possível que seu processo não esteja ligado à CPU, mas em vez disso, seja ligado a IO, como a rede ou o acesso ao disco ou ligado à memória. É difícil dizer sem mais detalhes sobre o que seu script está realmente fazendo quando é invocado.

EDITAR: Sua pergunta atualizada com informações sobre o uso da memória é reveladora, pois cada um de seus processos deseja 45m de RAM para si mesmo e está compartilhando 17m a mais. Com apenas 5 ou 6 processos em execução, você está excedendo a quantidade de RAM disponível. Essa é uma boa quantidade de memória para um script de baunilha Perl, o que está fazendo com ele?

Outras dicas

Esse não é um servidor muito grande. Poderia ser simplesmente desova o intérprete Perl que o torna ajoelhado? Carregar Perl (que eu felizmente presumo é mais de 1 MB) cinco vezes por segundo pode estar perguntando demais.

Obviamente, deve ser armazenado em cache, mas ainda precisará de inicialização antes de poder executar.

Enquanto que, pelos padrões de hoje, o servidor especificações não são impressionantes, eu tenho que correr bastante complicado coisas simultaneamente no hardware semelhante.No entanto, eu usei muito basico, executar somente o que é necessário FreeBSD configuração.(Semelhante ao que você pode realizar usando o ArchLinux).Eu suspeito que você não fazer um monte de configuração personalizada, e aceitou o Ubuntu padrões, que pode ser muito pesado para essas especificações.

Atualmente, eu estou a brincar com um Linode 360 e o desempenho é bom.

Agora, tudo isso é feito para dizer o óbvio:Precisamos de informações que você tem, que você não tenha compartilhado com a gente.Configuração do servidor Web, espaço de memória do script + intérprete, como muitos arquivos abertos, etc, etc.Tente fornecer o mais pequeno script que ainda apresenta o problema ou fornecer mais informações.

Atualização: Agora que eu vejo que você está usando mod_perl:1) você já fez a certeza de que todas as bibliotecas necessárias pelo script foram pré-carregados no servidor de início?2) você Está recebendo qualquer variable won't stay shared mensagens no log?3) você já leu mod_perl Desempenho? (Capítulo 10:Compartilhamento De Memória pode ser especialmente relevante).

Em geral, você deve pré-carregamento de bibliotecas comuns ao iniciar o servidor Apache.Como muito simplificado regra geral, quanto mais material permanece compartilhada, mais você pode sair do seu servidor.Ver Arquivo De Inicialização no Prática mod_perl.

Além disso, acho que 35MB por servidor é um pouco demais.Eu acho que você poderia cortar para baixo se você eliminado desnecessários módulos de configuração do Apache.No entanto, mesmo se você não pudesse, dizer tudo o que 35MB é compartilhado, mais o filho máximo o processo é de 50 mb, você deve ser capaz de acomodar cerca de 20 clientes ao mesmo tempo.

Só eu que notei que o script que você está testando.Realmente, tente pré-carregamento CGI na inicialização do servidor, adicionando as seguintes linhas ao seu startup.pl:

use strict;
use warnings;

use CGI();

Segundo, altere o script para

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

Observe que você nunca foi enviar o cabeçalho do script original (eu também odeio chamar um CGI instância $query por isso, tomei a liberdade de mudar isso também).Veja também O Perl De Referência.

Relatório de voltar a utilização de memória depois que.

Finalmente, por que você está dormindo de 5 segundos?AFAIK, Apache padrão do tempo limite para um script é de 3 segundos.

Que tipo de interface o script usa? Você certamente teria um desempenho melhor se pudesse evitar a execução do perl executável repetidamente, por exemplo, usando Fastcgi.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top