Отслеживаем медленные запросы или Почему тормозит Web-сервер
Бывают ситуации, когда Web-сервер тормозит, медленно выдает страницы, а что именно является причиной, непонятно. Первое что приходит в голову — поставить в скриптах контрольные точки, в которых фиксировать время выполнения скриптов. Это может быть достаточно трудной задачей, а при большой нагрузке и вовсе привести к зависанию. Поэтому сначала лучше попробовать встроенные средства Apache и MySQL: mod_status и лог медленных запросов.
Поскольку чаще всего источником проблем бывают запросы к базе данных, то начать следует с включения лога медленных запросов. Для этого в файл my.cnf (в секцию [mysqld]) прописываем:
[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql-slow.log
long_query_time=15
Перезапускаем MySQL. Теперь все запросы, которые будут выполняться более 15 секунд, будут записываться в файл, указанный в log-slow-queries с указанием времени выполнения и количества просмотренных рядов.
Если таких запросов слишком много, можно попробовать увеличить long-query-time.
Бывают ситуации, когда медленная работа сервера вызвана не SQL-запросами, а связана с медленной работой самих скриптов (например, из-за ошибок логики происходит зацикливание). Типичные признаки: в логе медленных запросов ничего подозрительного не наблюдается, а команда top показывает, что процессор сильно загружен и в памяти висит более десятка процессов httpd.
В этом случае полезно использовать модуль mod_status Web-сервера Apache. Этот модуль позволяет выводить страницу со списком URL обрабатываемых в данный момент запросов, их распределением по рабочим процессам, загрузкой процессора и некоторыми другими параметрами, которые могут помочь при отладке. Для того, чтобы включить этот модуль, нужно прописать в httpd.conf (или раскомментировать имеющуюся в файле по умолчанию) строку загрузки модуля:
LoadModule status_module modules/mod_status.so
После этого нужно указать, по какому адресу будет выводиться статистика с помощью директивы Location:
<Location /server-status>
SetHandler server-status
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
</Location>
Здесь /server-status — это URL, по которому будет доступна страница статистики. С точки зрения безопасности такую информацию крайне нежелательно показывать сторонним людям, поэтому следует ограничить доступ либо по IP (как в данном примере), либо паролем (это делается так же, как для обычного каталога с помощью auth_user), если же это по каким-то причинам делать нежелательно, то хотя бы указать вместо /server-status что-то трудноугадываемое.
Прописывать директиву Location можно как в основной конфигурации, так и для любого виртуального хоста. Но при этом важно помнить: на этом хосте не должен использоваться mod_rewrite (а точнее, правила с проверкой на существование каталога или файла), так как в противном случае будет происходить переадресация в соответствии с правилами mod_rewrite. Другой вариант — прописать правило для /server-status, в соответствии с которым переадресации происходить не будет.
Использование этих возможностей во многих случаях позволит выявить медленные запросы без больших правок в коде.