Вопрос

Я не могу заставить мой 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

Обновить

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

  • новый ()
  • сейчас ()
  • набор (...)
  • delta_ms(...)

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

Еще одна проблема.экземпляр mod_perl занимает много памяти.И я понятия не имею, почему.Я попытался запустить простой perl-скрипт, который не импортирует никаких модулей.Я запускаю его сразу после перезагрузки apache.Скрипт занимает 37 МБ памяти.Почему это происходит?Знаете ли вы, как заставить 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) в top utility увеличивается с 0% до 80% и остается высоким до тех пор, пока сценарии не будут выполнены.

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

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

Это было полезно?

Решение

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

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

Редактировать: Ваш обновленный вопрос с информацией об использовании вашей памяти показателен, поскольку каждый из ваших процессов требует 45 МЛН оперативной памяти для себя и использует еще 17 млн.При запуске всего 5 или 6 процессов вы превышаете объем доступной оперативной памяти.Это хороший объем памяти для использования скриптом vanilla Perl, что он с этим делает?

Другие советы

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

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

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

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

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

Обновить: Теперь, когда я вижу, что вы используете mod_perl:1) Убедились ли вы, что все библиотеки, необходимые скрипту, были предварительно загружены при запуске сервера?2) Получаете ли вы какие-либо variable won't stay shared сообщения в журнале?3) Читали ли вы производительность mod_perl? (Глава 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 секунды.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top