Недавно я заметил, что управляемый мною VPS имеет странное поведение Apache. По сути, любой HTTP-запрос зависает примерно на секунду, прежде чем он будет фактически обработан.
Выход из ab
показывает что-то вроде этого:
$ ab -n 10 -c 1 http://server-public-ip/path-to-static-file
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
<snipped>
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 3.5 0 11
Processing: 2 1373 1784.6 1000 4854
Waiting: 2 1372 1784.6 1000 4854
Total: 2 1374 1784.4 1011 4854
<snipped>
Сначала я подумал, что мой веб-сайт mod_perl работает медленно, но он работает со статически обслуживаемым файлом! Конфигурация моего виртуального хоста выглядит так:
<VirtualHost server-ip:80>
<Location />
DefaultType text/html
Order deny,allow
Allow from all
SetHandler perl-script
PerlHandler HTML::Mason::ApacheHandler
PerlSetVar MasonDataDir "/var/tmp/mason-cache"
PerlSetVar MasonCompRoot "<path-to-comproot>"
ReWriteEngine on
ReWriteRule ^(.*)/$ $1/index
ErrorDocument 404 /not_found
</Location>
<Location /static>
Order deny,allow
Allow from all
SetHandler default-handler
</LocationMatch>
</VirtualHost>
Имеется много свободной памяти (по крайней мере 32 МБ полностью свободно, т.е. не используется для кеширования), много ресурсов процессора (средняя загрузка составляет 0,00 в 1/5/15 минутных окнах), доступно много дискового ввода-вывода (средний диск скорость передачи менее 5 КБ / с). . . Понятия не имею, в чем может быть проблема. После начала передачи он работает на полной скорости (более 2 МБ / с, что примерно соответствует пределу моего локального соединения).
Я использую стабильную версию Debian с ядром 2.6.32 и Apache 2.2.16 (с использованием prefork). Трафик на сервер практически отсутствует, и я попытался настроить параметры предварительной вилки в обоих направлениях (много свободных воркеров, а запасных нет).
Есть предположения?
Имейте в виду, что даже если у вас есть отдельные обработчики для разных путей, дочерние элементы prefork будут повторно использоваться в зависимости от вашего MaxRequestsPerChild
настройка. Это означает, что дочерний элемент может в конечном итоге обслужить запрос к обработчику perl, прежде чем он обслужит его для статического содержимого (особенно если у вас есть балансировщик нагрузки с проверкой работоспособности обработчика perl). Если в Perl есть причуда, мешающая работе, он может склеивать статическое содержимое при последующих запросах.
По этой и другим причинам на предыдущем рабочем месте у нас была практика изолировать статический контент от его собственного процесса httpd и использовать балансировщик нагрузки для разделения трафика между ними на основе контекста URI. Второй веб-сервер даже не загружает mod_perl, изолируя любые проблемы, которые код создает для другого процесса.