Мой apache постоянно обслуживает около 300 запросов в секунду (2 мегабайта в секунду) при загрузке сервера 0,05.
Проблема в том, что моя сервисная архитектура вызывает огромный трафик в определенный момент (например, 300-500 человек перенаправляются на какую-то страницу с JavaScript за несколько секунд).
После такого короткого скачка трафика apache перестает отвечать (сброс соединения примерно через 30 секунд в firefox), ничего не регистрируя. Apache зависает до процедуры перезапуска apache2.
В замороженном состоянии он не может обслуживать даже простой HTML-файл без подключения PHP или SQL (но существуют процессы apache2)
Я пробовал разные настройки prefork от 50 до почти 1000 простаивающих рабочих и максимальное количество клиентов 10000, но ничего не помогает.
Еще один симптом, помимо того, что ничего не регистрирует, заключается в том, что за мгновение до зависания модуль состояния apache показывает (в последний раз, прежде чем он также перестает отвечать), что почти каждый процесс ожидает подключения:
__R_R_______R__RR______R___R________________RR_______R______R___
_________R__________R_________________________R________CR___R___
___________R__________________________C__WR__R________________R_
Но в обычной, менее загруженной работе он показывает:
C___R___K_C___C___C_____KK______R___C_C_R______C__K___C________K
____C__KR_RR__C___K___KK_C__R__K__C_CK__RC___CR___R__K__C__R____
___KR____C_____R______R______K__R_______KC__C_K__R____C_______R_
syslog тоже ничего не дает. Моя машина имеет 64 ГБ ОЗУ, и загрузка никогда не превышает 0,1
Я думаю, что когда ваши соединения увеличиваются со скоростью более 450 в секунду, это может быть связано с тем, что у вас заканчиваются эфемерные порты в Linux.
Проверьте это ранее ответил на вопрос
Небольшой отрывок из ответа:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
Диапазон временных портов определяет максимальное количество исходящих сокетов, которые хост может создать из определенного IP-адреса. адрес. Fin_timeout определяет минимальное время, в течение которого эти сокеты будут оставаться в состоянии TIME_WAIT (непригодны для использования после однократного использования). Обычные системные настройки по умолчанию:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
Это в основном означает, что ваша система не может гарантировать более (61000 - 32768) / 60 = 470 сокетов в любой момент времени. Если вас это не устраивает, вы можете начать с увеличения port_range. Установка диапазона на 15000 61000 в наши дни довольно распространена. Вы можете еще больше увеличить доступность, уменьшив fin_timeout. Предположим, вы делаете и то, и другое, вы должны с большей готовностью увидеть более 1500 исходящих соединений.
Можете ли вы подключиться к запущенному неотвечающему процессу и посмотреть, что произойдет? Может быть проще, если вы запустите prefork.
Присоединение к процессу с помощью трассировки
strace -p <pid> -o /tmp/somefile
Вы можете поиграть с -s
-s strsize Specify the maximum string size to print (the default is 32). Note that filenames are not considered strings and are always printed in full.
Я согласен с 3molo, strace может дать вам подсказку о том, что происходит, например, если есть системные вызовы, которые зависают. Единственное, в чем я не нашел помощника strace, - это проблемы с медленным io. Бег
sudo iotop
и
sudo top
Может дать некоторое представление о том, какой тип операций ввода-вывода происходит. В прошлом медленный ввод-вывод вызывал у меня подобное поведение; например, необходимость читать много очень маленьких файлов с медленного NAS. Если top сообщает о высоком «ожидании», а iotop показывает высокий процент пропускной способности, возможно, вам потребуется применить другое решение для хранения.
Начать нужно с двух вещей.
1) Установите уровень журнала для отладки в конфигурации apache. Всякий раз, когда у вас возникает проблемное поведение, просмотрите журналы доступа и журналы ошибок.
Предупреждение: Это может быстро заполнить ваш диск. Так что вернитесь от отладки к исходному значению, как только у вас будет достаточно информации.
2) Хотя я согласен с предложенной здесь опцией strace, я бы порекомендовал вам выполнить gdb при запущенном процессе. Если вам нужна дополнительная помощь о том, как отлаживать запущенный процесс, я рекомендую вам посмотреть этот.
Очень похоже на ограничение дескриптора файла. Тебе надо su
пользователю, от имени которого работает apache, а затем запустите это:
ulimit -n
По умолчанию во многих дистрибутивах установлено значение 1024. Если это так, попробуйте увеличить его. Вы можете изменить его в /etc/security/limits.conf в дистрибутивах на основе debian. Скажем, пользовательский apache работает как есть apache
, тогда вы можете добавить это:
apache soft nofile 65535
apache hard nofile 65535
Вам потребуется перезагрузка, чтобы применить это изменение.