Рассмотрим ситуацию: у вас на сервере хостится несколько сайтов работающих через mod_php под Apache 2.×. Вы обнаруживаете, что сервер начинает тормозить. Запускаете top
и видите, что верхние строчки занимает процесс apache2
(или httpd
). Ваша задача - узнать какой из сайтов и какими запросами грузит сервер. <!-more—>
Первый шаг — разрешить загрузку модуля mod_status
и сконфигурировать его в /etc/apache2/mods-available/status.conf
или в /etc/apache2/apache2.conf
(я буду писать пути и команды применительно к Debian):
<IfModule mod_status.c>
ExtendedStatus On
<Location /server-status>
SetHandler server-status
</Location>
</IfModule>
Можно опционально ограничить доступ к URL /server-status
по IP-адресу или даже поставить пароль.
Добавляем к любому сайту на сервере путь /server-status
и смотрим, что там показывается. Если видим много запросов к какому либо сайту в состоянии “W”, то можно предположить, что проблема с этим сайтом. Но это будет лишь гипотеза, так как узнать точно ситуацию по нагрузке, используя данный отчет, невозможно.
Используем хитрый ход. Установим модуль mod_perl
:
apt-get install libapache2-mod-perl2 apache2-prefork-dev
Пакет apache2-prefork-dev
нужен для последующей установки перловых модулей. Далее запустим cpan
и установим пару модулей:
cpan> install Sys::Proctitle
cpan> install Apache2::ShowStatus
В файл /etc/apache2/mods-available/perl.conf
добавим следующие строчки:
<IfModule mod_perl.c>
PerlModule Apache2::ShowStatus
PerlInitHandler Apache2::ShowStatus
</IfModule>
Проставим линк на этот файл и перезагрузим Apache:
ln -s /etc/apache2/mods-available/perl.conf /etc/apache2/mods-enabled/
apache2 -t
invoke-rc.d apache2 restart
Смотрим что из этого получилось:
# ps -o user,pid,%cpu,args --sort=-%cpu -u www-data | egrep '^USER|httpd' | grep -v grep
USER PID %CPU COMMAND
www-data 14039 0.6 httpd: GET /notices_item/????? HTTP/1.0
www-data 14073 0.5 httpd: GET /notice/???????.html HTTP/1.0
www-data 14069 0.5 httpd: GET /r_9/ HTTP/1.0
www-data 14075 0.5 httpd: GET /notice/???????.html HTTP/1.0
Я заменил часть URL-ов вопросиками из соображений конфиденциальности.
Ну что же, это неплохо, теперь мы видим отсортированные по полю %CPU процессы Apache, а так же видим, какой запрос они выполняют в данный момент. Но мы не видим к какому сайту относятся эти запросы. Придеться немного подпатчить модуль Apache2::ShowStatus
в файле /usr/local/share/perl/5.8.8/Apache2/ShowStatus.pm
:
--- ShowStatus.pm.orig 2009-01-22 14:19:26.122058102 +0300 +++ ShowStatus.pm 2009-01-22 14:21:01.030847967 +0300 @@ -16,7 +16,7 @@ my $r=shift;
$r->pnotes( 'ProctitleObject'=> - Sys::Proctitle->new( 'httpd: '.$r->the_request ) ); + Sys::Proctitle->new( 'httpd: ['.$r->get_server_name().'] '.$r->the_request ) );
return Apache2::Const::DECLINED; }
Перезагружаем Apache:
invoke-rc.d apache2 restart
Смотрим, что получилось:
# ps -o user,pid,%cpu,args --sort=-%cpu -u www-data | grep httpd | grep -v grep
www-data 16927 3.3 httpd: [www.????????.ru] GET /img_code.html HTTP/1.0
www-data 16885 3.2 httpd: [76.?????????.ru] GET /notices_item/???????/user_register/ HTTP/1.0
www-data 16921 1.0 httpd: [www.??????.ru] GET /products_item/?????? HTTP/1.0
www-data 16933 0.5 httpd: [www.????????.ru] GET /notice/????????.html HTTP/1.0
www-data 16878 0.5 httpd: [??????????.ru] GET /main_???????? HTTP/1.0
www-data 16930 0.2 httpd: [www.??????????.ru] GET /notice/??????????.html?sd=?????????????????????????????? HTTP/1.0
Ну вот, теперь мы видим и сайт, к которому пришел запрос, и сам запрос.
Кто еще какие способы использует для мониторинга нагрузки на хостинге в окружении Apache2 + mod_php5?