Почему мой скрипт mod_perl останавливает мой сервер? - PullRequest
1 голос
/ 09 октября 2009

Я не могу заставить мой Perl-скрипт работать стабильно на сервере. Вот проблема.

При обращении к сценарию более 5 раз в секунду сервер останавливается. И через некоторое время сервер зависает навсегда. SSH не отвечает, и я должен перезапустить сервер.

Я использую Apache с mod_perl.

Сценарий размещен на виртуальном выделенном сервере под Ubuntu. Я работаю через SSH. Это параметры сервера Процессор: 400 МГц Оперативная память: 256 МБ

Максимальное время выполнения скрипта составляет 200 миллисекунд.

Я контролировал загрузку сервера с помощью утилиты top. Не отображает никаких проблем, это статистика процессора при загрузке 5 скриптов в секунду:

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

Какие опции у меня есть, чтобы скрипт работал без проблем?

Это результат ps aux | fgrep perl в момент загрузки:

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

UPDATE

Я нашел узкое место. Я использовал модуль DateTime много раз вокруг кода. Следующие методы модуля DateTime выглядят очень медленными.

  • новый ()
  • сейчас ()
  • комплект (...)
  • delta_ms (...)

Я собираюсь заменить их быстрыми аналогами.

Еще одна проблема. Экземпляр mod_perl занимает много памяти. И я понятия не имею, почему. Я попытался запустить простой Perl-скрипт, который не импортирует никаких модулей. Я запускаю его сразу после перезагрузки Apache. Сценарий занимает 37M памяти. Почему это происходит? Вы знаете, как заставить mod_perl не использовать лишнюю память?

Обычный Perl-скрипт без поддержки mod_perl занимает 3-5 МБ памяти.

Ребята, спасибо за такую ​​помощь, я не ожидал такого чудесного ответа!

ОБНОВЛЕНИЕ 2

Я нашел еще один факт. Я создал простой Perl-скрипт, который просто ждет 5 секунд.

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

Тогда я породил много этих сценариев одновременно. Время невидимости (st) в верхней утилите увеличивается с 0% до 80% и остается на высоком уровне, пока не будут выполнены сценарии.

Откуда берется этот груз?

Кроме того, как я уже упоминал, каждый экземпляр perl занимает 36M памяти.

Ответы [ 4 ]

5 голосов
/ 09 октября 2009

Ваши цифры от top, кажется, указывают на то, что другие процессы вне вашей виртуальной машины замедляют ваш процессор, обратите внимание на последнее число, 87.2% st , которое указывает, что около 87% вашего процессорного времени используется выделенный вашим гипервизором для задач вне вашей виртуальной машины, даже если у вашей виртуальной машины есть вещи, которые он хотел бы запустить. Трудно сказать, связано это с вашей проблемой или нет.

Помимо обновления вашего сервера в соответствии с предложением unwind , с использованием постоянной среды процессов, как предлагается в zoul , возможно, что ваш процесс вообще не связан с процессором, а вместо этого - IO привязанный, например, к сети или к вашему диску, или связанный с памятью. Трудно сказать без подробностей о том, что на самом деле делает ваш скрипт, когда он вызывается.

РЕДАКТИРОВАТЬ: Ваш обновленный вопрос с информацией об использовании памяти является показательным, так как каждый из ваших процессов хочет 45M оперативной памяти для себя, и делится еще 17M. Всего 5 или 6 запущенных процессов превышают объем доступной оперативной памяти. Это хороший объем памяти для использования ванильным сценарием Perl, что он делает с ним?

3 голосов
/ 09 октября 2009

Это не очень большой сервер. Может ли это быть просто появление интерпретатора Perl, который заставляет его становиться на колени? Загрузка perl (которая, к счастью, превышает 1 МБ) пять раз в секунду может требовать слишком много.

Конечно, его следует кэшировать, но для выполнения все равно потребуется инициализация.

1 голос
/ 09 октября 2009

Хотя, по сегодняшним меркам, характеристики сервера не впечатляют, я одновременно запускал довольно сложные вещи на аналогичном оборудовании. Однако я использовал очень скелеты, запускаю только то, что необходимо для настройки FreeBSD. (Подобно тому, что вы можете достичь с помощью ArchLinux). Я подозреваю, что вы не сделали много пользовательских настроек и приняли значения по умолчанию Ubuntu, которые могут быть слишком тяжелыми для этих спецификаций.

В настоящее время я играю с Linode 360, и производительность в порядке.

Теперь все это означает очевидное: нам нужна ваша информация, которой вы не поделились с нами. Конфигурация веб-сервера, объем памяти скрипта + интерпретатора, количество открытых файлов и т. Д. Или попробуйте предоставить наименьший скрипт, который по-прежнему выявляет проблему, или предоставьте больше информации.

Обновление: Теперь, когда я вижу, что вы используете mod_perl: 1) Убедитесь, что все библиотеки, необходимые для скрипта, были предварительно загружены при запуске сервера? 2) Получаете ли вы какие-либо variable won't stay shared сообщения в журнале? 3) Вы читали mod_perl Performance ? ( Глава 10: Совместное использование памяти может быть особенно актуально).

Как правило, вы должны предварительно загружать общие библиотеки при запуске сервера Apache. Как очень простое практическое правило, чем больше материалов остается общим, тем больше вы можете получить от своего сервера. См. Файл запуска в Практический mod_perl .

Плюс, я думаю, что 35 МБ на сервер - это немного. Я думаю, что вы могли бы сократить это, если вы удалили ненужные модули из конфигурации Apache. Однако, даже если вы не можете, скажем, использовать все 35 МБ, плюс максимальный дочерний процесс составляет 50 МБ, вы сможете одновременно обслуживать около 20 клиентов.

Я только что заметил скрипт, который вы тестируете. Действительно, попробуйте предварительно загрузить CGI при запуске сервера, добавив следующие строки в ваш startup.pl:

use strict;
use warnings;

use CGI();

Во-вторых, измените этот скрипт на

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

Обратите внимание, что вы никогда не отправляли заголовок в исходном скрипте (я также ненавижу вызывать CGI экземпляр $query, поэтому я позволил себе также изменить его). Смотрите также Ссылка на Perl .

Сообщите об использовании памяти после этого.

Наконец, почему ты спишь 5 секунд? AFAIK, время ожидания Apache для скрипта по умолчанию составляет 3 секунды.

0 голосов
/ 09 октября 2009

Какой интерфейс использует скрипт? Вы, несомненно, получите лучшую производительность, если не будете запускать исполняемый файл perl снова и снова, например, используя FastCGI .

.
...