Я запускаю веб-приложение 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 Гбит / с.