Назад | Перейти на главную страницу

Как отлаживать таймауты apache?

Я запускаю веб-приложение PHP на сервере Apache 2.2 (Ubuntu Server 10.04, 8x2GHz, 12Gb RAM), используя prefork. Каждый день Apache получает около 100–200 тыс. Запросов, из которых около 100–200 достигает лимита тайм-аута (примерно один на каждую тысячу), почти все остальные запросы обслуживаются значительно меньше тайм-аута.

Что я могу сделать, чтобы узнать, почему это происходит? Или это нормально, когда время ожидания некоторых небольших частей всех запросов истекает?

Вот что я сделал до сих пор:

Как можно видеть, очень мало запросов, которые находятся между пределом тайм-аута и более разумным запросом. В настоящее время предел тайм-аута установлен на 50 секунд, ранее он был установлен на 300, и это была та же ситуация с некоторыми тайм-аутами, а затем огромным разрывом до других запросов.

Все запросы с истекшим временем ожидания AJAX запросы, но подавляющее большинство из них, так что, возможно, это скорее совпадение. Код возврата Apache: 200, но явно достигнут предел времени ожидания. Они принадлежат к разным IP-адресам.

Я просмотрел запросы, которые истекают по таймауту, и в них нет ничего особенного, если я выполняю те же запросы, которые они обрабатывают, менее чем за секунду.

Я попытался просмотреть различные ресурсы, чтобы узнать, могу ли я найти причину, но безуспешно. Всегда есть много свободной памяти (минимум около 3 ГБ), загрузка иногда достигает 1,4, а загрузка ЦП до 40%, но многие тайм-ауты происходят, когда загрузка и загрузка ЦП низкие. Запись / чтение с диска в течение дня практически постоянны. Нет записей в журнале медленных запросов MySQL (настроен на регистрацию чего-либо более 1 секунды), при отсутствии запроса используется такое количество операций записи / чтения из базы данных.

Синий - загрузка ЦП с пиком 40%, бордовый - загрузка с пиком 1,4. Таким образом, мы видим, что мы получаем тайм-ауты даже при низком использовании / загрузке ЦП (десятисекундные всплески хорошо соответствуют загрузке ЦП, но это еще одна проблема, у меня большие надежды выяснить, что может их вызывать).

В журнале ошибок Apache нет ошибок, и я не видел, чтобы он достиг более 200 активных процессов Apache.

Настройки сервера:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

Обновить:

Я обновился до Ubuntu 12.04.1, на всякий случай без изменений. Я добавил mod_reqtimeout с настройками:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Теперь почти все таймауты происходят в 10 секунд, один или два - в 20 секунд. Я полагаю, это означает, что в большинстве случаев получение тела запроса проблематично? Тело запроса никогда не должно быть больше нескольких сотен байтов. Я отслеживал сетевой трафик на 1-секундной основе, и он никогда не превышал 1 Мбит / с, и я не вижу никаких rxerrs или rxdorps, учитывая, что сервер находится на линии 1 Гбит / с, это не похоже на HopelessN00b написал о. Может быть, это просто плохое соединение с пользователем?

Что касается всплесков каждый час (они, кажется, немного смещаются, на графиках выше они показывают 33 минуты после часа, теперь они 12 минут), я попытался увидеть, есть ли что-нибудь периодически ( crons и т. д.), но ничего не нашел. Сборка мусора PHP выполняется два раза в час, но не во время всплесков, я все же пытался отключить ее, но это не имеет значения.

Я использовал dstat с --top-cpu и top, чтобы посмотреть на процессы во время всплесков, и все, что обнаружилось, - это apache, усердно работающий в течение нескольких секунд, но ни один другой процесс не использует значительный ЦП.

Я сделал увеличенный график шипов:

Мне кажется, что apache останавливается на несколько секунд, а затем усердно работает, чтобы обработать запросы, поступившие во время остановки. Что могло вызвать такую ​​остановку, или я неправильно это понимаю?

Первое, на что я обращаю внимание, глядя на ваш первый график, похоже, что наблюдается почасовое замедление (происходит примерно через 40 минут после часа), которое может способствовать возникновению проблемы. Вам следует взглянуть на планировщики задач в ОС / базе данных.

Основываясь на данных, которые вы предоставили, моим следующим шагом будет рассмотрение частоты времени отклика (количество ответов по оси Y против продолжительности по X), но только включая URL-адреса, которые показывают время ожидания (или предпочтительно по одному URL-адресу за раз. ). В типичной системе это должно следовать нормальному распределению или распределению Пуассона - запросы с тайм-аутом могут быть просто частью хвоста - и в этом случае вам нужно сосредоточить свои усилия на общей настройке. OTOH, если дистрибутив является бимодальным, вам нужно искать конфликты где-нибудь в вашем коде.

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

В блоге о сбоях сервера есть сообщение, Per Second Measurements Don't Cut It... возможно ли, что некоторые из этих запросов связаны с той же проблемой, с которой столкнулась команда ServerFault?

Мы обнаружили, что довольно часто отбрасываем пакеты на интерфейсах 1 Гбит / с со скоростью всего 10–30 Мбит / с, что снижает нашу производительность. Это связано с тем, что скорость 10-30 Мбит / с на самом деле представляет собой количество битов, передаваемых за 5 минут, преобразованное в скорость в одну секунду. Когда мы ближе познакомились с Wireshark и использовали графическое отображение ввода-вывода за одну миллисекунду, мы увидели, что мы часто взрываем скорость 1 Мбит на миллисекунду так называемых интерфейсов 1 Гбит / с.