Apache не отвечает и ничего не регистрируется после короткой, сильной "волны трафика"

Мой 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_

Системный журнал также ничего не дает. Моя машина имеет 64 ГБ оперативной памяти и никогда не превышает нагрузку 0,1

5 ответов

Я думаю, что когда скорость вашего соединения превышает 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 может дать вам подсказку о том, что происходит, например, если есть системные вызовы, которые зависают. Единственное, в чем я не нашел помощи, - это медленные проблемы. Бег

sudo iotop

а также

sudo top

Может дать некоторое представление о том, какой тип IO-активности происходит. Медленное IO вызывало подобное поведение в прошлом; например, необходимость читать много очень маленьких файлов с медленного NAS. Если top сообщает о большом "ожидании", а iotop показывает высокий процент пропускной способности, вам может потребоваться применить другое решение для хранения данных.

Очень похоже на ограничение дескриптора файла. Вам нужно su пользователю, который работает как Apache, а затем запустите это:

ulimit -n

По умолчанию на многих дистрибутивах установлено значение 1024. Если это так, попробуйте запустить его таким образом. Вы можете изменить его в /etc/security/limits.conf в дистрибутивах на основе Debian. Скажем, пользователь Apache работает как есть apacheтогда вы можете добавить это:

apache soft nofile 65535
apache hard nofile 65535

Вам нужно будет перезагрузиться, чтобы применить это изменение.

Вам нужно начать с двух вещей.

1) Установите loglevel для отладки в конфигурации apache. Всякий раз, когда у вас есть проблемы с поведением, посмотрите как журналы доступа, так и журналы ошибок.

Предупреждение: это может быстро заполнить ваш диск. Так что переключитесь с отладочного на его первоначальное значение, как только у вас будет достаточно информации.

2) Хотя я согласен с предложенным здесь вариантом strace, я бы порекомендовал вам сделать GDB при запуске процесса. Если вам нужна дополнительная помощь по отладке запущенного процесса, я бы порекомендовал вам это увидеть.

Другие вопросы по тегам