Апач умер вчера вечером. Журнал ошибок показывает это
[alert] (11)Resource temporarily unavailable: setuid: unable to change to uid: 48
Просматривая Интернет, кажется, что все говорят, что это проблема ulimit в Linux. Если я правильно понимаю, ulimit по умолчанию ограничивает количество одновременных процессов для любого пользователя без полномочий root до 1024. Если это максимальное число для пользователя (в данном случае apache) достигнуто, он не сможет создать больше процессов. Таким образом объясняется, почему он не может установить uid для пользователя apache, когда он попытался создать нового дочернего элемента.
Вчера вечером пользователь нашего веб-приложения сделал 1100+ запросов GET к одной и той же странице примерно за 1 минуту, и именно тогда сервер умер.
В моем конфигурационном файле Apache есть следующее:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 2000
MaxClients 2000
MaxRequestsPerChild 4000
</IfModule>
KeepAlive On
MaxKeepAliveTimeout 5
KeepAliveTimeout 5
Если мой MaxClients равен 2000, а MaxSpareServers равен 20, то это означает, что для того, чтобы Apache достиг ulimit для процессов, он должен был иметь 1000+ занятый процессы, которых я просто не вижу, учитывая, что эти GET-запросы были крошечными и могли легко обрабатывать 20-30 запросов в секунду. Вдобавок к этому MaxRequestsPerChild имеет значение 4000, поэтому он не должен порождать так много новых детей, верно? Так был ulimit действительно виноват здесь в том, почему он не может установить?
Я использовал Apache ab
инструмент, чтобы попытаться воспроизвести это на гораздо менее мощной локальной сборке, и я не могу. Даже менее мощное оборудование может обрабатывать тысячи подключений за одну минуту с хорошо производительность. Если я одновременно попытаюсь получить доступ к серверу через Интернет, это станет медленным, но Apache не упадет.
Итак, вот мои вопросы:
* hard nproc 15
, но Apache по-прежнему порождает около 30 детей, когда я запускаю ab
. Я что-то упускаю?iptables
для блокировки пользователей, сделавших более 5 SSH-запросов за минуту. Я думал о том, чтобы сделать что-то подобное для HTTP-запросов, но хотел узнать, есть ли лучшие решения. Я слышал о fail2ban, mod_security и т. Д., Но не уверен, что они делают. Принесут ли они мне пользу в этом случае? Есть другие предложения?Информация о сервере: RHEL 6.3, Apache 2.2.15